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.
Related
I have an application which starts giving me internal server error after some time, Some people I asked told me that this can be because of Connection leak in my application. I started searching and found this query to simulate connection leak.
select LAST_CALL_ET, SQL_TEXT, username, machine, to_char(logon_time, 'ddMon hh24:mi') as login, SQL_HASH_VALUE, PREV_HASH_VALUE, status from v$session, v$sql where username='USERNAME' and HASH_VALUE = PREV_HASH_VALUE
order by last_call_et desc;.
I monitored my application with this query and closed all leaked connections for the query shown in this result. But now my application is starting to give same error for even less inactive sessions .
Am I using the correct query to find out in active session / connection leak ? Someone told me condition HASH_VALUE = PREV_HASH_VALUE in this query is wrong, But I do not know about these columns (not much DB knowledge.)
Thank you
If you need to find out leaks you can use profilers like yourkit or jprofiler which is able to track socket/jdbc leaks.
To fix leaks you have to find out places where you opening connections and use try-with-resources which will do all close() stuff for you
try (Connection conection = DriverManager.getConnection(url);
PreparedStatement statement = createPreparedStatement(conection);
ResultSet resultSet = statement.executeQuery()) {
// process the resultSet here, all resources will be cleaned up
}
Most connection pools have a configuration to log connection leaks. I am not familiar with DBCP but the documentation indicates that the logAbandoned property will log connection leaks. If you set logAbandoned to true, DCBP should log stack traces some time after the pool timeout property. The stack trace will contain the location where the leaked connection was opened.
We are currently dealing with the function, that has to work partially with the database, and partially with a service, whice operations are time-consuming. So, generally speaking, here is a transactional method, that has a code like this:
Connection conn = null;
try {
conn = getConnection(); // This I get from the connection pool
Employee emp = queryDatabase(id);
// Point A - ??
Response resp = makeLongTimeServiceCall(emp);
// Point B - ??
anotherQueryDatabase(resp);
} catch (Exception e) {
throw e; // And this also rolls back the transaction
} finally {
// If conn is not closed, close it, so there would be no leaks
}
So the big question is - should I close the connection at point A and then get it again from the connection pool at point B, so that other servlets could use that connection while I interact with the service? My guess is that I should, but will this hurt my transaction?
In many circumstances: yes, closing and reopening the connection sounds good. However you need to understand the implication of doing them in two separate transactions (by closing and re-opening the connection you are inherently doing them in separate transaction).
If another user invokes an operation that changes the state of your data at Point B will the end result still be correct?
If you don't have a transaction you can close the connection and ask for a new connection when needed.
Remember that if you are using a connection pool closing a connection will not really close the connection, but only flag it as reusable by other threads.
Database connections shouldn't be left open. Open the connections just when you need to execute a query and close it as early as possible. So my solution is, YES.
if your application doesn't close connection properly may lead to some issues like the
connection pool maxing out.
Applications Not Properly Closing Connections:
When writing an application to use the WebSphere Application Server(WAS) datasource, the best way is fallowing get/use/close pattern.
1.get
-This is when the application makes a request to get a connection from the pool.
The application will first lookup the datasource name and then do a getConnection() call.
2.use
-This is when the application executes a query and waits for a response
3.close
-This is the final stage when the application has received the response from the database and is now done using that connection.
-The application should call close() in a finally block to close out the connection and return it to the free pool.
If your application does not follow this pattern, you may see connections staying open for long periods of time. This is especially seen when the application does not close the connection properly. After the response is received from the database, the application should be calling close in a finally block. If the application does not explicitly close the connection, that connection will stay open forever in WAS until that server is restarted. This is known as a connection leak. To resolve this type of issue, you will have to modify your application to close every connection
for further information: https://www.ibm.com/support/pages/common-reasons-why-connections-stay-open-long-period-time-websphere-application-server
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?
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;
Our standard code section for using JDBC is...
Connection conn = getConnection(...);
Statement stmt = conn.conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rset = stmt.executeQuery (sqlQuery);
// do stuff with rset
rset.close(); stmt.close(); conn.close();
Question 1: When using Connection Pool, should one close the Connection at the end? If so, isn't the purpose of pooling lost? And if not, how does the DataSource know when a particular instance of Connection is freed up and can be reused? I am a little confused on this one, any pointers appreciated.
Question 2: Is the following method anything close to standard? Looks like an attempt to get a connection from the pool, and if DataSource cannot be established, use the old fashioned DriverManager. We are not even sure which part is getting executed at runtime.
Repeating the question above, should one close the Connection coming out of such a method?
synchronized public Connection getConnection (boolean pooledConnection)
throws SQLException {
if (pooledConnection) {
if (ds == null) {
try {
Context envCtx = (Context)
new InitialContext().lookup("java:comp/env");
ds = (DataSource) envCtx.lookup("jdbc/NamedInTomcat");
return ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
}}
return (ds == null) ? getConnection (false) : ds.getConnection();
}
return DriverManager.getConnection(
"jdbc:mysql://"+ipaddy+":"+dbPort +"/" + dbName, uName, pWord);
}
Edit: I think we are getting the pooled connection since we do not see a stack trace.
When using Connection Pool, should one close the Connection at the end? If so, isn't the purpose of pooling lost? And if not, how does the DataSource know when a particular instance of Connection is freed up and can be reused? I am a little confused on this one, any pointers appreciated.
Yes, certainly you need to close the pooled connection as well. It's actually a wrapper around the actual connection. It wil under the covers release the actual connection back to the pool. It's further up to the pool to decide whether the actual connection will actually be closed or be reused for a new getConnection() call. So, regardless of whether you're using a connection pool or not, you should always close all the JDBC resources in reversed order in the finally block of the try block where you've acquired them. In Java 7 this can be further simplified by using try-with-resources statement.
Is the following method anything close to standard? Looks like an attempt to get a connection from the pool, and if DataSource cannot be established, use the old fashioned DriverManager. We are not even sure which part is getting executed at runtime. Repeating the question above, should one close the Connection coming out of such a method?
The example is pretty scary. You just need to lookup/initialize the DataSource only once during application's startup in some constructor / initialization of an applicationwide DB config class. Then just call getConnection() on the one and same datasource throughout the rest of application's lifetime. No need for synchronization nor nullchecks.
See also:
Is it safe to use a static java.sql.Connection instance in a multithreaded system?
Am I Using JDBC Connection Pooling?
The pools typically return you a wrapped Connection object, where the close() method is overridden, typically returning the Connection to the pool. Calling close() is OK and probably still required.
A close() method would probably look like this:
public void close() throws SQLException {
pool.returnConnection(this);
}
For your second question, you could add a logger to show whether the bottom block ever runs. I would imagine though you'd only want one way or the other for the configuration of your database connections. We solely use a pool for our database accesses. Either way, closing the connection would be pretty important to prevent leaks.
Actually, the best approach to connection management is to not farm them out to any code anywhere.
Create a SQLExecutor class that is the one and only location which opens and closes connections.
The entire rest of the application then pumps statements into the executor rather than getting connections from the pool and managing (or mismanaging them) all over the place.
You can have as many instances of the executor as you want, but no one should be writing code that opens and closes connections on its own behalf.
Conveniently, this also lets you log all your SQL from a single set of code.