Java DBCP2 Connection pooling is creating connection agian after max connection closed - java

I am attempting to use connection pooling using apache dbcp2.
My maxTotal connection is 5. I am closing every connection after it is used.
But still i am getting connection after 5 connection closed from connection pool.
whetehr it will ping database to get connection after 5 connections are closed ? or it will get from connection pool itself without going db.
Below is my sample code snippet. Please correct my understanding about connection pooling.
BasicDataSource bds = getBasicDataSource();
System.out.println (bds.getMaxTotal()); // Prints - 5
for (int i=0; i<10; i++) {
conn = bds.getConnection();
System.out.println("Conn "+conn); // conn object printing different values for all 10 connections
conn.close();
}

The connection a client gets from a pool is not really a java.sql.Connection, it's a wrapper (a proxy) for a java.sql.Connection that customizes the behavior of some methods. The close() method is one of them and does not close the Connection instance but returns it to the pool.
Try to use C3PO, from my point of view it is better than DBCP.

Related

Tomcat Connection pool : few methods not releasing connection

I am using tomcat connection pooling. But I was following exception
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object
So I put in the following lines in context.xml to find the leak :
removeAbandoned="true" logAbandoned="true" removeAbandonedTimeout="3"
Then I started getting following exception org.apache.tomcat.dbcp.dbcp.AbandonedTrace$AbandonedObjectException: DBCP object created 2015-01-17 22:12:18 by the following code was never closed:
So I found two culprit methods that were causing this leak. The two methods have common way of getting connection i.e. calling unwrap to get access to driver specific connection.
try (Connection conn = DataSourceConnectionPool.getConnection().unwrap(OracleConnection.class);
OracleCallableStatement cstmt = (OracleCallableStatement) conn.prepareCall(MIGRATE_ACCOUNT)) {
...
....
)
Important think to notice is that I am using try block from JDK7 i.e. Automatic Resource Management, so i dont need the finally block. Connection closing is handled by JDK automatically. But why this unwrapped connection is not closing. And when I am trying to do following :
try (Connection poolConn = DataSourceConnectionPool.getConnection();
Connection conn = poolConn.unwrap(OracleConnection.class);
I am getting java.sql.SQLException: Already closed. So how close this connection. Do I have to do it manually without using try block? Shouldn't try block handle be able to handle this?
This is incorrect usage of a connection pool. You should never call close() on an unwrapped connection.
The normal flow of using a pooled connection is
Get the Connection, the pool gets a physical connection and returns it wrapped in its own wrapper
You use the Connection
You call close() on the Connection. This doesn't actually close anything, the pool's wrapper intercepts the close() call and simply returns the (still active) connection to the pool.
This works because the pool has a wrapper class, say PoolableConnection that implements Connection. PoolableConnection delegates to the underlying connection for carrying out actual work, but it implements (amongst other things) close() differently. This destroys the current PoolableConnection wrapper and returns the underying Connection to the connection pool. For example.
This way, your program logic can get a connection from a DataSource, use the Connection and then close(), just as it would a normal, unpooled, Connection.
It's exactly this transparency that makes connection pools so easy to use.
Now, when you call unwrap, the PooledConnection gives you access to it's internal, real, Connection delegate.
What you do is call close() on the delegate!
This has two effects:
it does not call close() on PooledConnection, so the the Connection does not get returned to the pool.
it closes the underying connection from underneath the pool. This shouldn't be a problem, as the pool would deal with dropped connections itself.
So you need to be very careful. Always call close() on the Connection you have gotten from the pool, to return it to the pool. Never call close() on the underlying connection.
So your code should be:
try (final Connection poolConn = DataSourceConnectionPool.getConnection()) {
final Connection conn = poolConn.unwrap(OracleConnection.class);
//do stuff with conn
//do not close conn!!
}
//poolConn is returned to the pool

Closing connection in BoneCP

We have BoneCP library managing our connection pools. I'd like to know if the following statement will return the connection back to the pool.
statement = conn.createStatement();
....
lots of code.
....
Connection conn = statement.getConnection();
statement.close();
conn.close();
Will the above code close the connection and put the connection back into the pool?
Update:
I'm asking this question because when I run the statistics on connectionpool, i still see the conPool.getTotalLeased() showing that 2 connections are being used. But, I've closed the connections using the above mechanism.
The whole sense of a pool is to hold already established connections to your database. When you retrieve a connection from your pool you save the time to connect to your database.
What you are seeing is the pool holding your connections so it is all fine.
When you close your connection, it is only returned to the pool and marked as available for your next retrieval.
Yes it does moves the connection back to the pool. There was a mistake when getting the connection from the pool, fixed it, now i'm not seeing the 2 connections in the totalLeased() method.
Mistake that I found
conPool.getConnection(); // loitering connection which we see in the getTotalLeased();
..
Statement st = conPool.getConnection().getStatement(); //we have handle to this connection.
return st;

database connection pool purpose?

Considering a simple thread pool. The main purpose of a thread pool is reusing(recycling) a thread in order to limit the maximum number of threads and preventing of remove and create threads, am I right?
Recently I have read(wikipedia connection pool) that in Java EE, database connection are pooled by server, but I cannot figure out why?
Questions:
What is the main purpose of pooling sql connection in java?
Is it okay to pool 128 connections and keep all of them open?
What is the difference if 128 concurrent select commands get run by one connection or 128 connection?
What is the correct way to connect to the database through a connection pool?
How do both server and database handle the connections?
How does server reuse a closed connection?
Is pool still necessary when whole server components use a shared connection?
Thanks in advance.
Database connection pooling solve is very similar to the thread pooling you have mentioned here. Here are the main reasons.
Main purpose of the db connection pool is to create some db
connections and keep them in the pool and reuse them whenever your
application code need to execute queries to db. Because creation of
connections is a very costly operation, Connection pooling allows us
to save that effort.
It is perfectly fine to create 128 connections and keep them in the pool.
No 128 concurrent selects on one connection may not work properly. With connection pooling you get the connection from the
pool and the use it to fire all the queries that are required for the
operation and then you return the connection back to the pool. So you
would need 128 connections to run the concurrent selects.
Generally you let the container handle the connection pooling. You can configure connection pooling in web.xml or in the container
specify configuration file and associate a JNDI name with data source
that is connected to the pool. Then you lookup that DataSource and
get the connections from there. Here is the example code for getting
connections.
public static Connection getConnection() {
Connection con = null;
try {
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:/comp/env");
DataSource dataSource = (DataSource) envContext.lookup("jdbc/db");
con = dataSource.getConnection();
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
Database will assume that the connection are still alive and its the
responsibility of the application server to keep the connections in
the pool alive (of course by the configuration by user) and avoid the
connection timeouts.
When your application code requests the connection to be closed by calling connection.close(), This connection is not closed and is actually returned to the pool so that further requests for connections from the pool will use this connection.
For all web applications its is strongly advised that you create the connection pool else you will run into problems related to
performance and too many connections opened.

connection and session closing

I have the following code in the Try bloc :
// Session variable
Session session = null;
// Connection variable
Connection conn = null;
try {
...
// Get hibernate session
session = getHibernateTemplate().getSessionFactory().openSession();
// Get connection frojm session
conn = session.connection();
...
}catch{
...
}
And in the finally bloc i want to bloc all the related object of the connection with the database.
the closing of session makes us to close the connection ? or we have to have to close the connection before ?
Solution 1 :
finally{
try{if (conn!=null) conn.close();}ctach{}
try{if (session!=null) session.close();}catch{}
}
Solution 2 :
finally{
try{if (session!=null) session.close();}catch{}
}
In case of one of the two solutions before, can you explain the relationship between session and connection specially through pool way.
Second approach is enough. If you haven't set hibernate.connection.release_mode, then default (auto) is used. According documentation:
By default, a JDBC connection is held until the session is explicitly
closed or disconnected.
In case of pool, closing connection means that connection is returned to pool.
First, I like to know why you want to close connection in the code mentioned?
When you close a session hibernate makes sure that it does not hold any reference to the connection. In Hibernate 3.6.8, the call is delegated to the ConnectionManager. Check closeConnection() method. In Hibernate 4 when you call session.connection() what you get is a proxy and in hibernate 3, you are most likely get wrapper over connection, if connection pool is configured.
So your option is to debug session.connection() and session.close(), and decide whether you want to close the coneection or not.With the kind of information you provided, any answer here will be pure assumption.

c3p0 Connection Checkin

I'm trying to implement a solution with c3p0 for the first time. I understand how to initialize the connection pool and "checkout" a Connection from the pool as follows:
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass(driverClass);
cpds.setJdbcUrl(url);
cpds.setUser(username);
cpds.setPassword(password);
Connection conn = cpds.getConnection(username, password);
But I am having trouble finding out how to "checkin" an already used Connection to go back into the pool. How would I go about doing this? Is there something that I'm doing wrong here?
Freeing up is totally transparent to the user. See here for further explanation.
Be shure to close() the Connection and hold no further reference (that would avoid proper GC).
I believe the connection is returned to the pool when you close it.

Categories