部署在Tomcat上的DBCP中出现死锁问题

| 我正在Spring配置中使用DBCP数据源(具有默认配置)来管理与数据库的连接,并且当客户端数量增加时,我正陷入僵局。 我发现我正在使用的DBCP 1.2.1中存在一个死锁问题,应该在1.4中解决。所以我升级到1.4,但是问题仍然存在。 在线程转储中,有许多线程被阻塞,并在其顶部放置了以下堆栈跟踪:
   java.lang.Thread.State: WAITING on org.apache.commons.pool.impl.GenericObjectPool$Latch@b6b09e
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)
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.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:200)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:350)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:261)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:160)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:631)
欢迎任何建议!
已邀请:
几年前,我切换到了c3p0。你可以试试看。我相信您不必进行太多更改,这只是配置游戏。 与JDBC相关的线程,连接池选项:DBCP vs C3P0。好吧,实际上我使它与之相关。 [编辑,2012年10月19日] Tomcat 7有一个不错的连接池,即Tomcat JDBC连接池。
您确定公共池版本与dbcp版本匹配吗? 另外,我在堆栈跟踪中没有看到死锁,只是看起来您有等待连接释放的线程。您试图同时连接多少个线程?您为池等配置了多少个连接? 在调试这种情况下,查看已建立连接的线程在做什么也很有用。
应用程序负载的增加对并发连接的要求不断提高。由于您的线挂在
borrowConnection()
上-意味着您没有足够的
ActiveConnections
可用。 在数据源属性中增加
maxActive
,并将
WHEN_EXHAUSTED_BLOCK
设置为类似于
600ms - 1000ms
的时间。仅在经过600ms -1000 ms之后,您将获得
No element available
异常。
我认为这是由于未关闭应用程序代码中的连接导致的,因此您只用完了池中的连接。 也许您应该尝试在DBCP中设置\“ removeAbandoned \”属性。 这在http://commons.apache.org/dbcp/configuration.html中记录为 将此设置为true可以从编写不良的应用程序中恢复数据库连接 无法关闭连接。 祝你好运!
我遇到了类似的问题,可以通过以下步骤解决 按正确顺序关闭所有数据库资源
resultSet.close();
statement.close();
connection.close();
不同的驱动程序实现方式不同,如果未关闭基础resultSet,则某些驱动程序仍会启用连接。 Apache DBCP默认值需要调整
dataSource.setDefaultAutoCommit(true);
dataSource.setMaxActive(700); // make sure db server has it 800 dataSource.setRemoveAbandoned(true); dataSource.setTestOnBorrow(true); dataSource.setLogAbandoned(true); dataSource.setTestWhileIdle(true); dataSource.setTestOnReturn(true); dataSource.setRemoveAbandonedTimeout(60);
确保数据库服务器允许的至少50个以上的连接超过ѭ9中指定的数目,因为dbcp首先提供
x
个新连接,然后尝试清除超过
setMaxActive
个数目的连接。清理时,dbcp显示服务器日志/控制台上未关闭所有连接。

要回复问题请先登录注册