web-dev-qa-db-fra.com

DEADLOCK APPARENT Création de threads d'urgence pour des tâches en attente non attribuées

J'utilise mysql avec mybatis et je salue cette erreur sur notre serveur live

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

Je ne comprends pas pourquoi cette erreur vient, est-ce à cause de mon paramètre C3P0? Mes paramètres C3P0 sont comme ça 

---- start Mis à jour -----

ci-dessous est ma configuration de spring-servlet.xml

I - mis à jour datasource bean en tant que 

<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>  

et de ma classe Dao j'appelle la méthode de mappeur comme 

 myDao.updateRecords()

Ceci est ma méthode de classe de service

@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;
}

En classe de Dao, je viens d'injecter le mappeur. 

@Resource
private UserMapper userMapper;

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

--- fin mis à jour ------

s'il vous plaît laissez-moi savoir si d'autres informations sont nécessaires.

Ceci est la trace complète de la pile

[ 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)

---Mis à jour----

quand j'ai ajouté p: statementCacheNumDeferredCloseThreads = "1" au bean datasouce j'obtiens l'erreur ci-dessous

     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?
20
user965884

De http://www.mchange.com/projects/c3p0/#other_ds_configuration

numHelperThreads et maxAdministrativeTaskTime aident à configurer le comportement des pools de threads de source de données. Par défaut, chaque source de données n'a que trois threads auxiliaires associés. Si les performances semblent ralentir sous une charge importante ou si vous observez via JMX ou l'inspection directe d'un PooledDataSource que le nombre de "tâches en attente" est généralement supérieur à zéro, essayez d'augmenter numHelperThreads. maxAdministrativeTaskTime peut être utile pour les utilisateurs confrontés à des tâches qui se bloquent indéfiniment et aux messages "APPARENT DEADLOCK". (Voir l'annexe A pour plus d'informations.) 

maxAdministrativeTaskTime Par défaut: 0 Quelques secondes avant que le pool de threads de c3p0 ne tente d'interrompre une tâche apparemment bloquée. Rarement utile. La plupart des fonctions de c3p0 ne sont pas exécutées par les threads clients, mais de manière asynchrone par un pool de threads internes. L'asynchronisme de c3p0 améliore directement les performances du client et minimise la durée de conservation des verrous critiques en veillant à ce que les opérations jdbc lentes soient effectuées dans des threads ne conservant pas le verrouillage. Si, toutefois, certaines de ces tâches "se bloquent", c'est-à-dire qu'elles ne réussissent ni n'échouent avec une exception pendant une période prolongée, le pool de threads de c3p0 peut devenir épuisé et les tâches administratives sauvegardées. Si les tâches sont simplement lentes, le meilleur moyen de résoudre le problème consiste à augmenter le nombre de threads via numHelperThreads. Mais si les tâches sont parfois suspendues indéfiniment, vous pouvez utiliser ce paramètre pour forcer l'appel de la méthode interrupt () du thread de la tâche si une tâche dépasse une limite de temps définie. [c3p0 finira néanmoins par récupérer des tâches bloquées en signalant un "APPARENT DEADLOCK" (vous le verrez comme un avertissement dans les journaux), en remplaçant les threads de tâches du pool de threads et en interrompant () les threads d'origine. Mais laisser le pool aller dans APPARENT DEADLOCK et ensuite récupérer signifie que, pour certaines périodes, les performances de c3p0 seront altérées. Donc, si vous voyez ces messages, augmentation de numHelperThreads et la définition de maxAdministrativeTaskTime pourraient aider. maxAdministrativeTaskTime doit être suffisamment grand pour que toute tentative sérieuse d’acquérir une connexion à partir de la base de données, de tester une connexion ou de détruire une connexion, soit supposée réussir ou échouer dans le délai imparti. Zéro (valeur par défaut) signifie que les tâches ne sont jamais interrompues, ce qui constitue la politique la meilleure et la plus sûre dans la plupart des circonstances. Si les tâches sont simplement lentes, allouez plus de threads. Si les tâches sont en suspens pour toujours, essayez de comprendre pourquoi, et peut-être que définir maxAdministrativeTaskTime peut vous aider dans l’intervalle. 

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

setting maxAdministrativeTaskTime will help 
17
Manish Singh

Veuillez revoir les prochaines étapes pour résoudre le problème:

  1. Augmentez p:maxStatements dans ComboPooledDataSource.

  2. Définissez p:maxStatements sur 0. Par exemple, dans Firebird, ce hack fonctionne avec ComboPooledDataSource.

  3. Assurez-vous de fermer SqlSession dans votre application. Accorder plus d'attention à l'exécution intensive des opérations de base de données Dans ma version du pilote JDBC mySql: mysql-connector-Java 5.1.8 les connexions sont automatiquement fermées lorsque l'objet est nettoyé. Donc, dans votre cas, les connexions ne devraient pas fuir si vous n'utilisez pas la base de données de manière intensive. Néanmoins, vous devez être sûr de fermer myBatis SqlSession, qui connecte la connexion jdbc à la base de données.

  4. Aussi - Connexion JDBC3 et regroupement d’informations vous pouvez essayer de définir statementCacheNumDeferredCloseThreads sur 1 dans la configuration c3p0.

11
Taky

Dans mon cas, trop peu de mémoire pour l'application en était la cause. La base de données utilisée était soit H2, soit SQLite (les deux sont utilisés dans cette application).

Le premier symptôme était ces lignes de journal WARN comme indiqué ci-dessus:

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!

Suivi par des exceptions après une très longue période, y compris la révélation:

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

Le problème était reproductible. Donner plus de mémoire à l'application (-Xmx8G) a corrigé le problème.

0
Gonfi den Tschal