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;
Related
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.
I have a program that performs frequent requests to a database using a single-threaded workflow. The requests require obtaining connections within a second or less of each other, but one connection should always be closed before a new one is opened.
However, over time my debugging shows that the connections rack up rather quickly. It seems that connections start multiplying, and eventually reach the point where the program hangs because the connection pool's maximum (currently using BoneCP) is filled. I have the maximum set at 15, but it had similar behaviour when it was at the default number (8 I believe).
I am using try-with-resource statements, similar to the one below, to close the connections.
//Connection example
//Connection pool is configured.
DataSource source = new DataSource();
try (Connection con = source.getConnection();
PreparedStatement stmt = con.prepareStatement(query) {
//Do SQL stuff
} catch (SQLException e) {
//Handle Exception
}
If I understand try with resources right, this should automatically close the connection, and return it to the pool. Since this didn't work, I tried adding a con.close() statement in an attempt to better handle the connections. This quantitatively seemed to help, but I'm not sure it did anything in reality.
Why are so many connections being created, and how can I better manage my connections so I don't create so many?
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
I am using hikaricp as my database connection pool. I am closing the connection when I am done with my SQL statement by calling close on the connection which I believe you should return the connection proxy back to the pool . Yet, I see the following warning (not error) message and I have to wonder whether its an issue that needs to be addressed because I'm not cleaning up my connection resources properly. I am not using a try with resources but using a try catch finally (I close the connection in the finally & I realize that in certain conditions, the finally may actually not get called but it is being called in my case). any thoughts?
2014-09-15 13:59:26,083 WARN c.z.h.p.LeakTask [Hikari Housekeeping Timer (pool wmHikariCp)] Connection leak detection triggered, stack trace follows java.lang.Exception
at com.abc.test.DBConnPool.getConnection(DBConnPool.java:71)
at com.abc.test.TestProj.callDB(TestApp.java:30)
at com.abc.test.TestProj.main(TestApp.java:81)
Can you confirm whether you are indeed releasing the connection back to the pool? Can you use try with resources (in addition to increasing threshold as Brett mentioned):
try (Connection conn = DBConnectionPool.getConnection();
PreparedStatement ps = conn.prepareStatement(preparedQuery);) {
and the resultset (because some drivers/databases may not clean out resultset when connection is cleaned though not sure if this is still valid for new drivers/databases but I'm not sure what you are using):
try (ResultSet rs = ps.executeQuery();) {
Hope it helps.
There is a possibility that you are merely using the connection longer than the leak detection timeout. The leak detection is a threshold for how long a connection is out of the pool. Try increasing the threshold to a longer timeout.
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.