- 
                Notifications
    You must be signed in to change notification settings 
- Fork 38.8k
Description
Christopher G. Stach II opened SPR-6895 and commented
When JpaTransactionManager gets a handle for the Hibernate session's connection in doBegin with
ConnectionHandle conHandle = getJpaDialect().getJdbcConnection(em, definition.isReadOnly());
it never actually lets go. JpaTransactionManager eventually calls
getJpaDialect().releaseJdbcConnection(txObject.getConnectionHolder().getConnectionHandle(),
					txObject.getEntityManagerHolder().getEntityManager());
in doCleanupAfterCompletion, but HibernateJpaDialect has no implementation for releaseJdbcConnection.
Because this borrowed connection handle is never released, o.h.jdbc.ConnectionManager never returns the connection to the pool.
This setup eventually turns into a connection leak with Spring Web Flow when Hibernate fetches more connections to instantiate lazy collections and such, but the connection handles in the pool never get closed. Even if your database times out the connections and your pool eventually figures that out, the handles are still out of the pool until then.
After turning on debug logging for o.h.jdbc.ConnectionManager, things look like this:
$ grep jdbc.ConnectionManager debug.log | cut -c22- | sort | uniq -c
1 c.ConnectionManager.getConnection(ConnectionManager.java:167)
1 c.ConnectionManager.openConnection(ConnectionManager.java:446)
160 DEBUG jdbc.ConnectionManager aggressively releasing JDBC connection
157 DEBUG jdbc.ConnectionManager opening JDBC connection
156 DEBUG jdbc.ConnectionManager releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
1 DEBUG jdbc.ConnectionManager skipping aggresive-release due to borrowed connection
156 + 1 skipped release (and the two lines from the stack trace when the connection times out in the connection pool) = 157 opens.
$ grep jdbc.ConnectionManager debug.log | cut -c22- | sort | uniq -c
3 c.ConnectionManager.getConnection(ConnectionManager.java:167)
3 c.ConnectionManager.openConnection(ConnectionManager.java:446)
256 DEBUG jdbc.ConnectionManager aggressively releasing JDBC connection
251 DEBUG jdbc.ConnectionManager opening JDBC connection
248 DEBUG jdbc.ConnectionManager releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
3 DEBUG jdbc.ConnectionManager skipping aggresive-release due to borrowed connection
Again, 248 + 3 = 251.
Now, I don't see a need to have this JDBC connection even associated with the transaction as I do everything through JPA. I may be wrong about that, but it seems to only be used in this one spot. I went ahead and subclassed HibernateJpaDialect and made getJdbcConnection return null, just like DefaultJpaDialect. Things seem to be working, also (two separate runs):
$ grep jdbc.ConnectionManager debug.log | cut -c22- | sort | uniq -c
99 DEBUG jdbc.ConnectionManager aggressively releasing JDBC connection
95 DEBUG jdbc.ConnectionManager opening JDBC connection
95 DEBUG jdbc.ConnectionManager releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
$ grep jdbc.ConnectionManager debug.log | cut -c22- | sort | uniq -c
165 DEBUG jdbc.ConnectionManager aggressively releasing JDBC connection
161 DEBUG jdbc.ConnectionManager opening JDBC connection
161 DEBUG jdbc.ConnectionManager releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
The numbers match up and I am no longer getting timed out connections in the pool, which means I also shouldn't be running out of connections.
This should probably either be fixed, or this whole JDBC connection transaction association should be optional.
This was also described at http://ksevindik.blogspot.com/2008_11_01_archive.html.
Affects: 3.0 GA, 3.0.1
Issue Links:
- PooledConnection has already been closed exception with Hibernate 4.2 [SPR-10395] #15028 PooledConnection has already been closed exception with Hibernate 4.2
Referenced from: commits ef227c5