In recent versions of both DBCP and C3P0, using Spring Ibatis support, I ran into a problem when both connections leak.
The scenario is that there is a log running SQL that locks multiple tables. This leads to the maximum amount of connections in my pool, as users run queries that fall into locked tables. Finally, the administrator goes into MySQL and executes the kill query <id>
in long SQL.
If there are enough threads (in my case about 50 or more) that are waiting for the database thread to be checked back to the pool, then I see the following in the thread dump:
java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1315) at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557) - locked <0x00002aaacbb01118> (a com.mchange.v2.resourcepool.BasicResourcePool) at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477) at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525) at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128) at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:113) at
or
java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:485) at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1104) - locked <0x00002aab0f030620> (a org.apache.commons.pool.impl.GenericObjectPool$Latch) at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106) at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044) at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:113) at
and these threads are waiting around FOREVER.
This does not happen if the pool is exceeded, and only a few (about 5) threads are waiting for a free connection in the pool.
I know that there is a configuration that can solve this problem (timeout, etc.), but I wonder why this happens in the first place? Why are active threads not returning to the pool when there are 50 or more threads waiting to connect and I kill long SQL?
Update: I should have clearly indicated that I am using Spring 3.0.2 and Ibatis 2.3. I use SqlMapClientTemplate, which controls mine for me. At this point, I begin to think that this Ibatis 2.3 does not handle the heavy load correctly.
source share