JDBC connection pool management - java

I'm using org.apache.commons.dbcp.BasicDataSource as my datasource implementation, my code geting connection and closing the connection like this:
Connection conn = dataSource.getConnection();
when I finished the connection work I will close it
conn.close();
My question is: the conn.close() is really close, so when the connection be closed like conn.close(), how is datasource doing. I heard that the datasource connection close is not really close, just is release, but I can't find the release API from datasource class. I want to know how does datasource manage the creation, close and release of database connection.
By the way a little question: how does datasource refresh the connection, I mean if the connections of the datasource haven't been used for one year, how does datasource keep the connections available?

DataSource (javax.sql.DataSource) represents an abstract concept of something you can get database connections from.
So, DataSource itself doesn't define any details of how connections are managed, and different implementations of DataSource may manage connections in different ways:
A naive implementation (such as Spring's DriverManagerDataSource) may create a new connection each time you request it, and in this case close() actually closes connections.
An implementation backed by a connection pool (such as Apache DBCP or c3p0) returns existing connections from the pool. Connection object returned by such an implementation is a proxy, and its close() method is overriden to return connection to the pool instead of closing it.
If you want to know how exactly your connection pool manages connections, check documentation of your connection pool implementation.

The close() call on a connection from a datasource doesn't necessarily close the database connection. It would merely return the connection to the pool for reuse. The way this is done is, the actual connection to the database is decorated with a PooledConnection sort of class and the close() method on this PooledConnection is overridden to just mark the connection as available.

Related

which is better for operate db from java jdbc

that's a question which has confuse me a lot.
for example:
when I design the Dao layer,sometimes,I must do some insert operation,and than
I should do some query such as select the data's id by auto-generate in db.
my question was that:
when I use spring to help manage datasource,
when I do more than two sql operation one by one,
how many times the java client connect to the db?? only one ? or more?
code,such as fellows:
getSimpleJdbcTemplate().update(some params...);
getSimpleJdbcTemplate().query(some params...);
It depends on your Transactional settings.
Spring-transactions in local mode, work on a thread-local connection for all the db activities within single transaction.
If you have not configured transactions, then basically each DB call will retrieve connection from datasource using Datasource.getConnection()
In terms client connecting to DB, if you are using datasource with connection pooling capability, then connections are returned from the pool.
But if datasource is not backed by pool, then it will instantiate connection to DB server on demand ( on getConnection() ) call

how to return connection to pool

do we need to call any method on dbcp.BasicDataSource or jndi datasource(i'm using jboss) to return the connection after done with it?
Nope, just call Connection.close(). If this connection was obtained from a pooled data source, then it won't actually be closed, it'll just be returned to the pool.

Hibernate Session Connection Relationship

How many connection will hold for a single hibernate session where there is only one DB?
there is one connection per session.
the connection is opened only if the session needs to send JDBC queries
you should avoid using the underlying connection. The connection() method has been deprecated. If you need to perform raw jdbc operations, use the doWork(..) method (if your hibernate version is the latest)
At a given time given session will only hold one connection
which you can access with the connect() method.
The connection used can be changed though using the reconnect() method.

When should we close the EntityManagerFactory?

I am pretty new on the ORM's. I just start to read books and documents about Java Persistence API with Hibernate.
I just wondered, closing EntityManagerFactory is similar with jdbc database connection closing?
Should we close it after every persist/update/delete or not? If we don't close it, will the database connection stay opened?
I just wondered, closing EntityManagerFactory is similar with jdbc database connection closing?
This is not exactly true but closing an EntityManagerFactory would be closer to destroying a whole connection pool. If you want to think JDBC connection, you should think EntityManager.
Should we close it after every persist/update/delete or not?
Creating an EntityManagerFactory is a pretty expensive operation and should be done once for the lifetime of the application (you close it at the end of the application). So, no, you should not close it for each persist/update/delete operation.
The EntityManagerFactory is created once for all and you usually get an EntityManager per request, which is closed at the end of the request (EntityManager per request is the most common pattern for a multi-user client/server application).
If we don't close it, will the database connection stay opened?
As hinted, it's the EntityManager that is actually associated to a database connection and closing the EntityManager will actually release the JDBC connection (most often, return it to a pool).

Am I using Java PooledConnections correctly?

I want to use pooled connections with Java (because it is costly to create one connection per thread) so I'm using the MysqlConnectionPoolDataSource() object. I'm persisting my data source across threads. So, I'm only using one datasource throughout the application like this:
startRegistry(); // creates an RMI registry for MySQL
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
dataSource.setUser("username");
dataSource.setPassword("password");
dataSource.setServerName("serverIP");
dataSource.setPort(3306);
dataSource.setDatabaseName("dbname");
InitialContext context = createContext(); // Creates a context
context.rebind("MySQLDS", dataSource);
Now that I have my datasource created, I'm doing the following in each separate thread:
PooledConnection connect = dataSource.getPooledConnection();
Connection sqlConnection = connect.getConnection();
Statement state = sqlConnection.createStatement();
ResultSet result = state.executeQuery("select * from someTable");
// Continue processing results
I guess what I'm confused on is the call to dataSource.getPooledConnection();
Is this really fetching a pooled connection? And is this thread safe?
I noticed that PooledConnection has methods like notify() and wait()... meaning that I don't think it is doing what I think it is doing...
Also, when and how should I release the connection?
I'm wondering if it would be more beneficial to roll my own because then I'd be more familiar with everything, but I don't really want to reinvent the wheel in this case :).
Thanks SO
This is not the right way. The datasource needs to be managed by whatever container you're running the application in. The MysqlConnectionPoolDataSource is not a connection pool. It is just a concrete implementation of the javax.sql.DataSource interface. You normally define it in the JNDI context and obtain it from there. Also MySQL itself states it all explicitly in their documentation.
Now, how to use it depends on the purpose of the application. If it is a web application, then you need to refer the JNDI resources documentation of the servletcontainer/appserver in question. If it is for example Tomcat, then you can find it here. If you're running a client application --for which I would highly question the value of a connection pool--, then you need to look for a connection pooling framework which can make use of the MySQL-provided connection pooled datasource, such as C3P0.
The other problem with the code which you posted is that the PooledConnection#getConnection() will return the underlying connection which is thus not a pooled connection. Calling close on it won't return the connection to the pool, but just really close it. The pool has to create a new connection everytime.
Then the threadsafety story, that depends on the real connection pooling framework in question. C3P0 has proven its robustness in years, you don't worry about it as long as you write JDBC code according the standard idiom, i.e. use only the JDBC interfaces and acquire and close all resources (Connection, Statement and ResultSet) in shortest possible scope.

Categories