C3p0 APPARENT DEADLOCK异常

11

我在Tomcat日志中一直收到这个异常:

com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@76b28200 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@76b28200 -- APPARENT DEADLOCK!!! Complete Status: 
    Managed Threads: 3
    Active Threads: 3
    Active Tasks: 
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@1201fd18 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@408f3be4 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@7ba516d8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
    Pending Tasks: 
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@137efe53
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@766b0524
Pool thread stack traces:
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
        java.lang.Thread.sleep(Native Method)
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1805)
        com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
        java.lang.Thread.sleep(Native Method)
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1805)
        com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
        java.lang.Thread.sleep(Native Method)
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1805)
        com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

我正在使用Hibernate 3.6.2和C3P0 0.9.1.2与MySQL。经过几个小时的谷歌搜索,这个明显的死锁异常似乎通常与准备语句缓存有关。这是我的hibernate.cfg.xml中的C3P0配置:


I am using Hibernate 3.6.2 and C3P0 0.9.1.2 with MySQL. After a couple of hours of searching Google, this APPARENT DEADLOCK exception seems to be usually associated with prepared statement caching. This is my C3P0 configuration in my hibernate.cfg.xml:
<propertyname="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.acquire_increment">5</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">60</property>
<property name="hibernate.c3p0.idle_test_period">120</property>
<property name="hibernate.c3p0.timeout">180</property>              
<property name="hibernate.c3p0.max_statements">0</property>

我没有做任何语句缓存。非常感谢任何指出问题的提示。

3个回答

11

造成死锁的任务是连接获取任务。也就是说,c3p0正试图从您的数据库获取新连接,并且这些连接获取尝试需要很长时间。

我会首先升级到0.9.2.1版本,该版本在采取一轮连接获取尝试时,具有更改进的性能,可以解决连接获取失败的情况。

如果这不能解决问题,则需要找出为什么c3p0获取连接的尝试会长时间挂起:既不成功,也不抛出异常。


升级我的c3p0到0.9.2.1版本似乎起了作用!感谢@SteveWaldman提供的提示。 - corderazo00
显然它没有起作用,APPARENT DEADLOCK又回来了...有没有一种方法可以更密切地监视c3p0的活动或在更低的级别上查看为什么在尝试获取连接时它会挂起? - corderazo00
清除Web服务器(tomcat/work/Catalina)的缓存是否会与此有关?我找到了一些线程,人们声称这解决了他们的问题。 - corderazo00
2
Tomcat的热部署存在许多地雷,特别是在像c3p0这样会生成新线程的库中容易出现PermGen内存泄漏问题。即将发布的c3p0-0.9.5-pre4版本可能会在一两天内推出,其中将增加一些新设置以防止这些泄漏问题,可以将新的配置参数privilegeSpawnedThreads设置为true,contextClassLoaderSource设置为library。建议等待一两天并尝试使用该版本! - Steve Waldman
我完全同意Steve的观点,Tomcat的热部署确实非常接近于“俄罗斯轮盘”式的选项。 如果您尝试了建议的选项,请告诉我们结果,我非常好奇。 - sataniccrow
在我们的情况下,是我们的服务器被阻止与MySQL服务器通信。com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 通信链接失败,最后一个数据包成功发送到服务器的时间为0毫秒。驱动程序没有从服务器接收到任何数据包。 - M. Rizzo

1
在我的特定情况下,问题与我部署应用程序的服务器配置有关。只有在打印出应用程序的堆栈跟踪后,才发现它挂起,因为Oracle驱动程序正在等待生成安全随机数。
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
  java.io.FileInputStream.readBytes(Native Method)
  java.io.FileInputStream.read(FileInputStream.java:255)
  sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedBytes(SeedGenerator.java:539)
  sun.security.provider.SeedGenerator.generateSeed(SeedGenerator.java:144)
  sun.security.provider.SecureRandom$SeederHolder.(SecureRandom.java:203)
  sun.security.provider.SecureRandom.engineNextBytes(SecureRandom.java:221)
  java.security.SecureRandom.nextBytes(SecureRandom.java:468)
  oracle.security.o5logon.O5Logon.a(Unknown Source)
  oracle.security.o5logon.O5Logon.(Unknown Source)
  oracle.jdbc.driver.T4CTTIoauthenticate.(T4CTTIoauthenticate.java:582)
  oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401)
  oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:553)
  oracle.jdbc.driver.T4CConnection.(T4CConnection.java:254)
  oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
  oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:528)
  com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134)
  com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
  com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
  com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
  com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
  com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
  com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
  com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

然后我不得不学习和了解一些关于熵噪声的知识,并且在我的Unix朋友的帮助下,意识到其中一个服务器没有安装生成“噪声”的软件包。
如下帖子所述,我运行了以下命令: cat /proc/sys/kernel/random/entropy_avail 23 cat /proc/sys/kernel/random/poolsize 4096 因此,可用的熵太少,无法生成安全的随机数。
安装软件包后, cat /proc/sys/kernel/random/entropy_avail 4096 之后,我再也没有遇到明显的死锁,我的应用程序可以连接到数据库。

http://www.usn-it.de/index.php/2009/02/20/oracle-11g-jdbc-driver-hangs-blocked-by-devrandom-entropy-pool-empty/


0

之前遇到过类似的错误。

这也可能是由于数据库服务器阻止了您的IP而引起的。确保您的服务器IP未被数据库服务器/云服务提供商阻止。

在我的情况下,我尝试使用多线程将数据插入到云数据库中,它只能在本地工作,但在服务器上(不同网络)无法工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接