如何跟踪和防止在单独进程中运行的c3po中出现的死锁?

我有一个非常简单的计算,它产生字母矩阵可能找到矩阵中的所有单词。 单词中的字母是相邻的单元格。

for (int i = 0; i < 500; i++) { System.out.println(i); Matrix matrix = new Matrix(4); matrix.scanWordsRandomly(9); matrix.printMatrix(); System.out.println(matrix.getSollSize()); matrix.write_to_db(); } 

这是持久代码。

 public void write_to_db() { Session session = null; try { session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); Matrixtr onematrixtr = new Matrixtr(); onematrixtr.setDimension(dimension); onematrixtr.setMatrixstr(this.toString()); onematrixtr.setSolsize(getSollSize()); session.save(onematrixtr); for (Map.Entry<Kelimetr, List> sollution : sollutions.entrySet()) { Kelimetr kelimetr = sollution.getKey(); List solpath = sollution.getValue(); Solstr onesol = new Solstr(); onesol.setKelimetr(kelimetr); onesol.setMatrixtr(onematrixtr); onesol.setSoltext(solpath.toString().replace("[", "").replace("]", "").replace("true", "").replace("false", "")); session.save(onesol); } session.getTransaction().commit(); session.close(); } catch (HibernateException he) { System.out.println("DB Error : " + he.getMessage()); session.close(); } catch (Exception ex) { System.out.println("General Error : " + ex.getMessage()); } } 

这是hibernate配置文件。

     org.hibernate.dialect.MySQLDialect com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/kelimegame_db_dev?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 root !.Wlu9RrCA false org.hibernate.hql.classic.ClassicQueryTranslatorFactory false  50 10 100 300 5 3000         

在找到所有可能的解决方案后,我使用hibernate来保持矩阵和解决方案。 我也在使用c3pO库。 我没有产生任何线程。 所有的工作都是以一种非常简单的迭代方式完成的。 但是我在不同的进程中运行jar。 从不同的终端我执行这个:

 java -jar NewDB.jar 

我遇到了如下僵局:

 Apr 25, 2013 8:38:05 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@7f0c09f9 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! Apr 25, 2013 9:08:23 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@7f0c09f9 -- APPARENT DEADLOCK!!! Complete Status: Managed Threads: 3 Active Threads: 3 Active Tasks: com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@2933f261 on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#1 com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@116dd369 on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#0 com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@41529b6f on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#2 Pending Tasks: com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@165ab5ea com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@1d5d211d com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@4d2905fa Pool thread stack traces: Thread[C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#1,5,main] com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:662) Thread[C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#0,5,main] com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:662) Thread[C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#2,5,main] com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:662) Apr 25, 2013 9:41:29 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@7f0c09f9 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks! Apr 25, 2013 9:55:18 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@7f0c09f9 -- APPARENT DEADLOCK!!! Complete Status: Managed Threads: 3 Active Threads: 3 Active Tasks: com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@5a337b7d on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#0 com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@69f079ce on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#1 com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@2accf9b8 on thread: C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#2 Pending Tasks: com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@771eb4fb com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@fc07d6 com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@2266731b com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@740f0341 com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@59edbee com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@78e924 com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask@2123aba com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@7acd8a65 Pool thread stack traces: Thread[C3P0PooledConnectionPoolManager[identityToken->z8kfsx8uibeyqevbbapc|4045cf35]-HelperThread-#0,5,main] java.text.NumberFormat.getInstance(NumberFormat.java:769) java.text.NumberFormat.getInstance(NumberFormat.java:393) java.text.MessageFormat.subformat(MessageFormat.java:1262) java.text.MessageFormat.format(MessageFormat.java:860) java.text.Format.format(Format.java:157) java.text.MessageFormat.format(MessageFormat.java:836) com.mysql.jdbc.Messages.getString(Messages.java:106) com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2552) com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002) com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2991) com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3532) com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:943) com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:4113) com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1308) com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2336) com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2176) com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2158) com.mysql.jdbc.ConnectionImpl.(ConnectionImpl.java:792) com.mysql.jdbc.JDBC4Connection.(JDBC4Connection.java:47) sun.reflect.GeneratedConstructorAccessor7.newInstance(Unknown Source) sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) java.lang.reflect.Constructor.newInstance(Constructor.java:525) com.mysql.jdbc.Util.handleNewInstance(Util.java:411) com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:381) com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305) com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134) com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:183) com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:172) com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:188)Killed caglar@ubuntu:~/NetBeansProjects/NewDB/dist$ 

我的问题如下:

  1. 因为我在不同的进程中运行程序,所以c3po中的这种僵局会发生吗?
  2. 我应该在此过程中使用一个进程和多个线程吗?
  3. 我怎样才能追踪这个死锁,了解它的原因? 有没有办法跟踪多个导致死锁的JVM?

这是一个有趣的。

你发表了两个不同的APPARENT DEADLOCKS。 第一个是由c3p0尝试关闭()连接引起的,而那些close()操作既没有成功也没有及时失败。 第二个APPARENT DEADLOCK显示连接获取问题:c3p0正在尝试获取新的连接,并且这些尝试既没有成功也没有及时失败。 事实上,非常不同的操作正在冻结,这表明你的dbms在你正在做的事情或某些事情的压力下锁定可能是一个更普遍的问题。 对您的数据库运行多个进程应该没问题,但您需要了解限制。

您的配置有一些有趣的事情:

1)hibernate.c3p0.max_statements = 5是一个非常糟糕的主意,几乎在任何池上,特别是在这么大的池上。 你有多达100个连接,并且你只允许在所有连接之间缓存总共5个语句。 这可能会对池和DBMS造成压力,因为您将不断地通过PreparedStatements进行搅拌,并且语句缓存会对此进行大量的记录。 您可能意味着每个连接需要5个缓存语句,但这不是您配置的内容。 您已为池设置了全局最大值。 也许尝试hibernate.c3p0.maxStatementsPerConnection = 5? 或者将max_statements设置为零以关闭语句缓存,至少在解决死锁之前。 请参阅http://www.mchange.com/projects/c3p0/#configuring_statement_pooling

2)如果你在多个进程而不是多个线程中运行计算,你真的需要每个进程保持50 – 100个连接吗? 事情可能正在冻结,因为您正在强调具有太多Connections优秀的dbms,因为每个多个进程都会获得大量资源密集型连接。 在任何进程中都不需要更多的连接,而不是在该进程中并发运行客户端线程。 我将hibernate.c3p0.acquire_increment和hibernate.c3p0.max_size设置为更小的值。

3)如果你确实需要同时运行所有这些连接,你可以通过将配置参数numHelperThreads增加到某个大于其默认值3的值来减少池的漏洞。你可能希望numHelperThreads是数字的两倍您的计算机上可用的核心数。 鉴于您正在运行多个进程,您可能会发现自己正在使CPU饱和,这会让事情变得更加困难。 所以要注意这一点。

基本上,尝试更新您的配置,以便尽可能高效地使用资源 – 文件句柄,网络连接,CPU – 这样您就不会不必要地压缩池/语句缓存/ dbms。

如果这些建议无法解决问题,请发布您的池的填充配置。 c3p0在池初始化时将其配置转储到INFO级别。

祝好运!