web-dev-qa-db-ja.com

割り当てられていない保留中のタスクの緊急スレッドの作成

Mybatisでmysqlを使用しており、ライブサーバーでこのエラーを表示しています

com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@6538f8f2 
-- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!

C3P0の設定が原因でこのエラーが発生する理由がわかりません。私のC3P0設定はこのようなものです

----更新開始-----

以下は私のspring-servlet.xml設定です

I 更新 datasource bean as

<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" p:driverClass="com.mysql.jdbc.Driver"
p:jdbcUrl="jdbc:mysql://localhost/jdb" p:user="root" p:password="root" 
p:acquireIncrement="10" 
p:idleConnectionTestPeriod="60"
p:maxPoolSize="100" 
    p:maxStatements="0" 
    p:minPoolSize="10" 
    p:initialPoolSize="10"
    p:statementCacheNumDeferredCloseThreads="1" />
   <!-- Declare a transaction manager -->

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="datasource" />


<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="datasource" />
</bean>

<!-- scan for mappers and will automatically scan the whole classpath for xmls -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    <property name="basePackage" value="com.mycom.myproject.db.mybatis.dao" />
</bean>  

daoクラスからマッパーメソッドを呼び出します

 myDao.updateRecords()

これは私のサービスクラスメソッドです

@Override
public List<UserDetailedBean> selectAllUsersDetail(long groupId, List<Long> ids) {

    List<UserDetailedBean> usersDetailList = null;

    try {
        usersDetailList = userDao.selectAllUsersDetail(groupId, ids);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return usersDetailList;
}

Daoクラスでは、マッパーを注入するだけです。

@Resource
private UserMapper userMapper;

@Override
public List<UserDetailedBean> selectAllUsersDetail(long groupId, List<Long> ids) {
    return userMapper.selectAllUsersDetail(groupId,ids);
}

---終了更新------

他の情報が必要な場合はお知らせください。

これは完全なスタックトレースです

[ WARN] 2013-01-08 20:13:39       com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@70497e11 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
[ WARN] 2013-01-08 20:13:39 com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@70497e11 -- APPARENT DEADLOCK!!! Complete Status: 
 Managed Threads: 3
 Active Threads: 3
 Active Tasks: 
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@2e81b8c5 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@4689a55d (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@76c7a0d8 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
 Pending Tasks: 
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@2c1101d4
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@108f1be6
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@2370a188
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@377cf9e5
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@6dfa45d8
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@49ffa050
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask@2d760a24
    Pool thread stack traces:
 Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
     Java.net.SocketInputStream.socketRead0(Native Method)
     Java.net.SocketInputStream.read(SocketInputStream.Java:150)
     Java.net.SocketInputStream.read(SocketInputStream.Java:121)
     com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.Java:114)
     com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.Java:161)
     com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.Java:189)
     com.mysql.jdbc.MysqlIO.readFully(MysqlIO.Java:2549)
     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.sendCommand(MysqlIO.Java:2002)
     com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.Java:2163)
     com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.Java:2618)
     com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.Java:2568)
     com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.Java:1557)
     com.mysql.jdbc.DatabaseMetaData$9.forEach(DatabaseMetaData.Java:4984)
     com.mysql.jdbc.IterateBlock.doForAll(IterateBlock.Java:51)
     com.mysql.jdbc.DatabaseMetaData.getTables(DatabaseMetaData.Java:4962)
     com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnectionNoQuery(DefaultConnectionTester.Java:185)
     com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnection(DefaultConnectionTester.Java:62)
     com.mchange.v2.c3p0.AbstractConnectionTester.activeCheckConnection(AbstractConnectionTester.Java:67)
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.Java:368)
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishIdleResource(C3P0PooledConnectionPool.Java:310)
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask.run(BasicResourcePool.Java:1999)
     com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:547)
 Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
     Java.net.SocketInputStream.socketRead0(Native Method)
     Java.net.SocketInputStream.read(SocketInputStream.Java:150)
     Java.net.SocketInputStream.read(SocketInputStream.Java:121)
     com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.Java:114)
     com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.Java:161)
     com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.Java:189)
     com.mysql.jdbc.MysqlIO.readFully(MysqlIO.Java:2549)
     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.sendCommand(MysqlIO.Java:2002)
     com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.Java:2163)
     com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.Java:2618)
     com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.Java:2568)
     com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.Java:1557)
     com.mysql.jdbc.DatabaseMetaData$9.forEach(DatabaseMetaData.Java:4984)
     com.mysql.jdbc.IterateBlock.doForAll(IterateBlock.Java:51)
     com.mysql.jdbc.DatabaseMetaData.getTables(DatabaseMetaData.Java:4962)
     com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnectionNoQuery(DefaultConnectionTester.Java:185)
     com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnection(DefaultConnectionTester.Java:62)
     com.mchange.v2.c3p0.AbstractConnectionTester.activeCheckConnection(AbstractConnectionTester.Java:67)
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.Java:368)
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishIdleResource(C3P0PooledConnectionPool.Java:310)
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask.run(BasicResourcePool.Java:1999)
     com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:547)
 Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
     Java.net.SocketInputStream.socketRead0(Native Method)
     Java.net.SocketInputStream.read(SocketInputStream.Java:150)
     Java.net.SocketInputStream.read(SocketInputStream.Java:121)
     com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.Java:114)
     com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.Java:161)
     com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.Java:189)
     com.mysql.jdbc.MysqlIO.readFully(MysqlIO.Java:2549)
     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.sendCommand(MysqlIO.Java:2002)
     com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.Java:2163)
     com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.Java:2618)
     com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.Java:2568)
     com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.Java:1557)
     com.mysql.jdbc.DatabaseMetaData$9.forEach(DatabaseMetaData.Java:4984)
     com.mysql.jdbc.IterateBlock.doForAll(IterateBlock.Java:51)
     com.mysql.jdbc.DatabaseMetaData.getTables(DatabaseMetaData.Java:4962)
     com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnectionNoQuery(DefaultConnectionTester.Java:185)
     com.mchange.v2.c3p0.impl.DefaultConnectionTester.activeCheckConnection(DefaultConnectionTester.Java:62)
     com.mchange.v2.c3p0.AbstractConnectionTester.activeCheckConnection(AbstractConnectionTester.Java:67)
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.testPooledConnection(C3P0PooledConnectionPool.Java:368)
     com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.refurbishIdleResource(C3P0PooledConnectionPool.Java:310)
     com.mchange.v2.resourcepool.BasicResourcePool$AsyncTestIdleResourceTask.run(BasicResourcePool.Java:1999)
     com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:547)

---更新済み----

datasouce Beanにp:statementCacheNumDeferredCloseThreads = "1"を追加すると、次のエラーが表示されます。

     Error creating bean with name 'sqlSessionFactory' defined in ServletContext resource [/WEB-INF/spring-servlet.xml]: 
     Cannot resolve reference to bean 'datasource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'datasource' defined in ServletContext resource [/WEB-INF/spring-servlet.xml]: 
   Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'statementCacheNumDeferredCloseThreads' of bean class [com.mchange.v2.c3p0.ComboPooledDataSource]: 
   Bean property 'statementCacheNumDeferredCloseThreads' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
21
user965884

から http://www.mchange.com/projects/c3p0/#other_ds_configuration

numHelperThreadsおよびmaxAdministrativeTaskTimeDataSourceスレッドプールの動作を構成するのに役立ちます。デフォルトでは、各DataSourceには3つの関連するヘルパースレッドのみがあります。パフォーマンスが高負荷下で低下するように見える場合、またはJMXまたはPooledDataSourceの直接検査で観察する場合、「保留中のタスク」の数は通常0より大きいことを確認するには、numHelperThreadsを増やしてみてください。 maxAdministrativeTaskTimeは、無期限にハングするタスクと「APPARENT DEADLOCK」メッセージを経験しているユーザーに役立つ場合があります。 (詳細については、付録Aを参照してください。)

maxAdministrativeTaskTimeデフォルト:0 c3p0のスレッドプールが明らかにハングしたタスクに割り込もうとする前の0秒。あまり役に立たない。 c3p0の機能の多くは、クライアントスレッドによって実行されるのではなく、内部スレッドプールによって非同期的に実行されます。 c3p0の非同期性により、クライアントのパフォーマンスが直接向上し、ロックを保持していないスレッドで低速のjdbc操作が確実に実行されるため、重要なロックが保持される時間が最小限に抑えられます。ただし、これらのタスクの一部が「ハング」する場合、つまり、長期間にわたって例外で成功も失敗もしない場合、c3p0のスレッドプールは使い果たされ、管理タスクがバックアップされる可能性があります。タスクが単純に遅い場合、問題を解決する最善の方法は、numHelperThreadsを介してスレッドの数を増やすことです。ただし、タスクが無期限にハングすることがある場合、このパラメーターを使用して、タスクが設定された制限時間を超えた場合にタスクスレッドのinterrupt()メソッドを強制的に呼び出すことができます。 [c3p0は最終的にハングしたタスクから回復します。 "APPARENT DEADLOCK"(ログに警告として表示されます)を通知し、スレッドプールタスクスレッドを置き換え、元のスレッドに割り込みます。ただし、プールをAPPARENT DEADLOCKにしてから回復させると、一定期間c3p0のパフォーマンスが低下します。したがって、これらのメッセージが表示される場合は、numHelperThreadsを増やしてmaxAdministrativeTaskTimeを設定すると役立つ場合があります。 maxAdministrativeTaskTimeは、データベースから接続を取得したり、接続をテストしたり、接続を破棄したりする妥当な試行が、設定された時間内に成功または失敗するのに十分な大きさでなければなりません。ゼロ(デフォルト)は、タスクが中断されないことを意味します。これは、ほとんどの状況で最も安全なポリシーです。タスクが遅い場合は、より多くのスレッドを割り当てます。タスクが永遠にハングする場合は、その理由を理解してみてください。その間にmaxAdministrativeTaskTimeを設定すると役立つ場合があります。

The default is 3 for numHelperThreads , increase this to 8-10 

setting maxAdministrativeTaskTime will help 
17
Manish Singh

次の手順を確認して問題を修正してください。

  1. 増加する p:maxStatements ComboPooledDataSourceで。

  2. セットする p:maxStatements〜0。たとえば、Firebirdでは、このハックはComboPooledDataSourceで機能します。

  3. アプリケーションで SqlSession を必ず閉じてください。データベース操作を集中的に実行することにもっと注意を払ってください。 mySql JDBCドライバーの私のバージョンでは: mysql-connector-Java 5.1.8 オブジェクトがガベージコレクションされると、接続は自動的に閉じられます。したがって、データベースを集中的に使用していない場合、接続がリークすることはありません。それでも、DBへのjdbc接続をラップするmyBatis SqlSessionが近いことを確認する必要があります。

  4. また、それに応じて JDBC3接続とステートメントプーリングstatementCacheNumDeferredCloseThreads1c3p0構成。

11
Taky

私の場合、アプリケーションのメモリが少なすぎることが原因でした。使用されたDBはH2またはSQLiteでした(両方ともこのアプリで使用されています)。

最初の症状は、上記で報告されたこれらのWARNログ行でした。

12006925 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|33af2d37]-AdminTaskTimer] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner  - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@6d3a9c65 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
12016284 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|3d98d1b]-AdminTaskTimer] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner  - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@44565f94 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
12051847 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|5703a6aa]-AdminTaskTimer] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner  - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@c9f37e2 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
12085128 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|4e50d42b]-AdminTaskTimer] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner  - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@6f1927b7 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
12085128 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|78fa7f84]-AdminTaskTimer] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner  - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@22c22b50 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
12172644 [C3P0PooledConnectionPoolManager[identityToken->2rvy8f9szmpczp1k2dm1g|e8e88fa]-AdminTaskTimer] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner  - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@745a644f -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!

非常に長い時間を経て、明らかになったものを含む例外が続きます。

Caused by: Java.lang.OutOfMemoryError: GC overhead limit exceeded

問題は再現可能でした。アプリにより多くのメモリ(-Xmx8G)を与えると修正されました。

0