在最新版本的DBCP和C3P0上,使用Spring的Ibatis支持,我遇到了两个泄漏连接的问题。带C3P0或DBCP的Spring ORM正在泄漏连接
该方案是有一个运行SQL的日志锁定多个表。这会导致我的池中的连接在用户触发锁定表的查询时最大化。最后,管理员进入MySQL并在长时间运行的SQL上执行kill query <id>
。
如果有足够的线程(在我的周围50个或更多的情况下),它正在等待绕了DB线程在游泳池进行检查回来,然后我看到类似线程转储如下:
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
或
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
和这些线程等待撒手人寰。
如果该池已最大化,并且只有少数(约5个)线程正在等待池中的空闲连接,则不会发生这种情况。
我知道有配置可以解决这个问题(设置超时等),但我有兴趣为什么这是发生在第一个地方?为什么当有50个或更多的线程在等待连接,并且我终止了长时间运行的SQL时,活动线程不会返回到池中?
更新:我应该明确表示,我使用Spring 3.0.2和 ibatis的2.3。我使用SqlMapClientTemplate,它为我管理我的 连接。此时,我开始认为它是 Ibatis 2.3没有正确处理重负载。
您是否在执行查询后关闭连接? – BalusC
@BalusC我对Spring使用ComboPooledDataSource或BasicDataSource,所以我不管理在我的Java代码中关闭这些连接的open c。也许春天是问题。 – stevebot
你应该显示一些你如何使用连接的代码。仅仅因为你使用Spring来管理数据源,并不意味着它会为你关闭连接。 – Nick