【发布时间】:2011-12-11 02:07:41
【问题描述】:
在 DBCP 和 C3P0 的最新版本上,使用 Spring 的 Ibatis 支持,我遇到了两个泄漏连接的问题。
场景是有一个日志运行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 和 伊巴蒂斯 2.3。我使用管理我的 SqlMapClientTemplate 为我连接。在这一点上,我开始认为它是 Ibatis 2.3 无法正确处理重负载。
【问题讨论】:
-
执行查询后是否关闭连接?
-
@BalusC 我在 Spring 中使用 ComboPooledDataSource 或 BasicDataSource,因此我不管理在我的 Java 代码中打开 c 关闭这些连接。也许春天是问题所在。
-
你应该展示一些你如何使用连接的代码。仅仅因为您使用 Spring 来管理数据源,并不意味着它会为您关闭连接。
-
@Nick 实际上确实如此,只需阅读源代码即可。您将 DataSource 传递给 SqlMapClientTemplate,它管理获取和关闭您的连接。
-
抱歉,不太清楚您使用的是
SqlMapClientTemplate。
标签: java mysql database spring c3p0