【问题标题】:How to handle hibernate Deadlock? (c3p0)如何处理休眠死锁? (c3p0)
【发布时间】:2019-04-12 14:36:35
【问题描述】:

当休眠DeadlockDetector(com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector)识别DEADLOCK,反复出现SQL ERROR 1205(Lock wait timeout)时,c3p0的所有线程都卡住了,hole应用程序冻结。
我对避免死锁本身的解决方案不感兴趣,但对以编程方式对此做出反应的可能性不感兴趣。

在这种情况下,其他一些应用程序在数据库服务器上产生了一个表锁。 在我杀死应用程序(SIGKILL)并重新启动后一切都很好。

APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
SQL Error: 1205, SQLState: 40001
Lock wait timeout exceeded; try restarting transaction

使用过的版本:
c3p0:0.9.5.2
休眠:5.0.0.CR1
完全没有弹簧。

完整的堆栈跟踪:

2019-04-12 15:04:27,102 [WARN ] Slf4jMLog$Slf4jMLogger$WarnLogger (C3P0PooledConnectionPoolManager[identityToken->2s35s8a24vskkqigquy5|31304f14]-AdminTaskTimer) - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4d710599 -- APPARENT DEADLOCK!!! Creating
emergency threads for unassigned pending tasks!
2019-04-12 15:04:27,104 [WARN ] Slf4jMLog$Slf4jMLogger$WarnLogger (C3P0PooledConnectionPoolManager[identityToken->2s35s8a24vskkqigquy5|31304f14]-AdminTaskTimer) - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4d710599 -- APPARENT DEADLOCK!!! Complete
Status:
Managed Threads: 3
Active Threads: 3
Active Tasks:
com.mchange.v2.c3p0.stmt.GooGooStatementCache$StatementDestructionManager$1UncheckedStatementCloseTask@679ab26c
on thread: C3P0PooledConnectionPoolManager[identityToken->2s35s8a24vskkqigquy5|31304f14]-HelperThread-#2
com.mchange.v2.c3p0.stmt.GooGooStatementCache$StatementDestructionManager$1UncheckedStatementCloseTask@c9f62bd
on thread: C3P0PooledConnectionPoolManager[identityToken->2s35s8a24vskkqigquy5|31304f14]-HelperThread-#0
com.mchange.v2.c3p0.stmt.GooGooStatementCache$StatementDestructionManager$1UncheckedStatementCloseTask@6250fbb8
on thread: C3P0PooledConnectionPoolManager[identityToken->2s35s8a24vskkqigquy5|31304f14]-HelperThread-#1
Pending Tasks:
com.mchange.v2.c3p0.stmt.GooGooStatementCache$StatementDestructionManager$1UncheckedStatementCloseTask@4cdc18cd
com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@7ee7dae8
com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@99ac503
com.mchange.v2.c3p0.stmt.GooGooStatementCache$1StmtAcquireTask@6cf272b3
com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@40c40590
com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@34b7fa
com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@5f59d822
com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@20414e90

Pool thread stack traces:

Thread[C3P0PooledConnectionPoolManager[identityToken->2s35s8a24vskkqigquy5|31304f14]-HelperThread-#2,5,main]
com.mysql.jdbc.PreparedStatement.realClose(PreparedStatement.java:2689)
com.mysql.jdbc.StatementImpl.close(StatementImpl.java:534)
com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:53)
com.mchange.v2.c3p0.stmt.GooGooStatementCache$StatementDestructionManager$1UncheckedStatementCloseTask.run(GooGooStatementCache.java:934)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)

Thread[C3P0PooledConnectionPoolManager[identityToken->2s35s8a24vskkqigquy5|31304f14]-HelperThread-#0,5,main]
com.mysql.jdbc.PreparedStatement.realClose(PreparedStatement.java:2689)
com.mysql.jdbc.StatementImpl.close(StatementImpl.java:534)
com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:53)
com.mchange.v2.c3p0.stmt.GooGooStatementCache$StatementDestructionManager$1UncheckedStatementCloseTask.run(GooGooStatementCache.java:934)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)

Thread[C3P0PooledConnectionPoolManager[identityToken->2s35s8a24vskkqigquy5|31304f14]-HelperThread-#1,5,main]
com.mysql.jdbc.PreparedStatement.realClose(PreparedStatement.java:2689)
com.mysql.jdbc.StatementImpl.close(StatementImpl.java:534)
com.mchange.v1.db.sql.StatementUtils.attemptClose(StatementUtils.java:53)
com.mchange.v2.c3p0.stmt.GooGooStatementCache$StatementDestructionManager$1UncheckedStatementCloseTask.run(GooGooStatementCache.java:934)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)

    #tread 1
2019-04-12 15:04:28,795 [WARN ] SqlExceptionHelper (qtp1548271808-41) - SQL Error: 1205, SQLState: 40001
2019-04-12 15:04:28,797 [ERROR] SqlExceptionHelper (qtp1548271808-41) - Lock wait timeout exceeded; try restarting transaction
    #tread 2
2019-04-12 15:05:18,799 [WARN ] SqlExceptionHelper (qtp1548271808-23) - SQL Error: 1205, SQLState: 40001
2019-04-12 15:05:18,800 [ERROR] SqlExceptionHelper (qtp1548271808-23) - Lock wait timeout exceeded; try restarting transaction
    #tread 3
2019-04-12 15:05:18,799 [WARN ] SqlExceptionHelper (qtp1548271808-22) - SQL Error: 1205, SQLState: 40001
2019-04-12 15:05:18,801 [ERROR] SqlExceptionHelper (qtp1548271808-22) - Lock wait timeout exceeded; try restarting transaction

【问题讨论】:

  • 表观死锁应该打印出哪些任务被阻止的转储。这对调试很有帮助。如果可以,请添加。
  • 我已经通过编辑帖子添加了堆栈跟踪

标签: hibernate c3p0 database-deadlocks


【解决方案1】:

APPARENT DEADLOCK 数据转储中,很明显您遇到了由于尝试关闭缓存语句冻结而导致的死锁。对于 c3p0 语句缓存和某些(尤其是 Oracle 和 jTDS)JDBC 驱动程序的交互,这是一个已知问题/脆弱性。

有两种方法可以解决此问题。最简单的一种是禁用语句缓存:确保 c3p0 配置参数 maxStatementsmaxStatementsPerConnection 都设置为零。

如果您希望从语句缓存中获得性能优势,c3p0 有一个setting to work around this issueTL; DR: 添加 c3p0 配置属性 c3p0.statementCacheNumDeferredCloseThreads=1

【讨论】:

    猜你喜欢
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2013-11-22
    • 2017-11-15
    • 1970-01-01
    • 2012-09-06
    相关资源
    最近更新 更多