带有C3P0或DBCP的Spring ORM正在泄漏连接

ste*_*bot 4 java mysql database spring c3p0

在DBCP和C3P0的最新版本上,使用Spring的Ibatis支持,我遇到了两个泄漏连接的问题.

方案是有一个运行SQL的日志来锁定多个表.这会导致我的池中的连接最大化,因为用户触发了锁定表的查询.最后,管理员进入MySQL并对kill query <id>长时间运行的SQL执行操作.

如果有足够的线程(在我的情况下大约50个或更多)等待将数据库线程重新检入池中,那么我在线程转储中看到如下内容:

 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 
Run Code Online (Sandbox Code Playgroud)

要么

  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 
Run Code Online (Sandbox Code Playgroud)

这些线程在FOREVER等待.

如果池被最大化,并且只有少数(大约5个)线程正在等待池中的空闲连接,则不会发生这种情况.

我知道有配置可以解决这个问题(设置超时等),但我感兴趣的是为什么这首先发生?当有50个或更多线程等待连接并且我终止长时间运行的SQL时,为什么活动线程没有返回到池?

更新:我应该明确表示我使用的是Spring 3.0.2和Ibatis 2.3.我使用SqlMapClientTemplate来管理我的连接.此时,我开始认为Ibatis 2.3没有正确处理重负载.

mre*_*isz 5

使用c3po时,我强烈建议您尝试使用此功能.在事务外执行数据库修改时,通常会出现连接泄漏.与uncommited写入的连接无法重用,并且会从池中丢失.如果使用相当长的超时启用此调试,您将能够看到具有可疑数据库操作的堆栈跟踪.

确保堆栈跟踪中看到的操作正确管理事务.还可以通过将c3p0记录器设置为调试级别来监视连接池的使用情况.