Как справиться со спящим тупиком? (C3p0) - PullRequest
0 голосов
/ 12 апреля 2019

Когда DEADLOCK распознается hibernates DeadlockDetector (com.mchange.v2.async.ThreadPoolAsynchronousRunner $ DeadlockDetector) и SQL ERROR 1205 (тайм-аут ожидания блокировки), все потоки c3p0 зависли, и дырочное приложение зависло.
Меня не интересуют решения, позволяющие избежать самой тупиковой ситуации, а возможности программно реагировать на это.

В этом случае какое-то другое приложение произвело блокировку таблицы на сервере базы данных. После того, как я убил приложение (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

1 Ответ

0 голосов
/ 15 апреля 2019

Из дампа данных APPARENT DEADLOCK становится ясно, что вы столкнулись с тупиковыми ситуациями из-за попыток заморозить закрытые кэшированные операторы.Это известная проблема / уязвимость в отношении взаимодействия кэширования операторов c3p0 и некоторых (особенно Oracle и jTDS) драйверов JDBC.

Существует два способа решения этой проблемы.Самый простой - отключить кэширование операторов: убедитесь, что параметры конфигурации c3p0 maxStatements и maxStatementsPerConnection установлены на ноль.

Если вы получаете выигрыш в производительности, который вы хотитеДержитесь подальше от кэширования операторов, c3p0 имеет настройку , чтобы обойти эту проблему . TL;DR: добавить свойство конфигурации c3p0 c3p0.statementCacheNumDeferredCloseThreads=1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...