web-dev-qa-db-fra.com

C3P0 blocage apparent lorsque les threads sont tous vides?

J'utilise C3P0 comme pool de connexion dans Tomcat et je constate des erreurs très préoccupantes:

2010-09-16 13:25:00,160 [Timer-0] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner  - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@43502400 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
2010-09-16 13:25:01,407 [Timer-0] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner  - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@43502400 -- APPARENT DEADLOCK!!! Complete Status:
  Managed Threads: 10
  Active Threads: 0
  Active Tasks:
  Pending Tasks:
    com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@6e4151a7
  Pool thread stack traces:
  Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#6,5,main]
    Java.lang.Object.wait(Native Method)
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:534)
  Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
    Java.lang.Object.wait(Native Method)
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:534)
  Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
    Java.lang.Object.wait(Native Method)
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:534)
  Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
    Java.lang.Object.wait(Native Method)
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:534)
  Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#5,5,main]
    Java.lang.Object.wait(Native Method)
    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:534)
  Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#4,5,main]
    Java.lang.Object.wait(Native Method)

... many more, exact same stack trace

La ligne 534 est:

 while (true) {
   Runnable myTask;
   synchronized ( ThreadPoolAsynchronousRunner.this ) {
     while ( !should_stop && pendingTasks.size() == 0 )
       ThreadPoolAsynchronousRunner.this.wait( POLL_FOR_STOP_INTERVAL ); // <- here
     if (should_stop) ...

Il semble que tous les fils sont inactifs. Ils attendent du travail. 0 threads actifs, et seulement 1 tâche à terminer. Des indices sur ce qui ne va pas?

Voici la configuration:

ds.setUser(userName);
ds.setPassword(password);
ds.setMaxPoolSize(16);
ds.setMaxConnectionAge(1800);
ds.setAcquireRetryAttempts(4);
ds.setMaxIdleTime(900);
ds.setNumHelperThreads(10);
ds.setCheckoutTimeout(1000);
27
Steven Schlansker

Je viens de rencontrer un problème similaire avec une base de données Oracle, mais dans mon cas, les nombres Managed Thread et Active Thread étaient les mêmes.

    Managed Threads: 3
    Active Threads: 3

Pour moi, il s’agissait d’une erreur d’authentification mais d’une erreur APPARENT DEADLOCK en raison de la manière dont je procédais à l’audit de connexion. 

    2013-08-12 11:29:04,910 [Timer-4] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@34996454 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
    2013-08-12 11:29:04,914 [Timer-4] WARN  com.mchange.v2.async.ThreadPoolAsynchronousRunner: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@34996454 -- APPARENT DEADLOCK!!! Complete Status: 
            Managed Threads: 3
            Active Threads: 3
            Active Tasks: 
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@6730b844 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@2f91ad49 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@507ac05 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
            Pending Tasks: 
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@3aae7ed7
    Pool thread stack traces:
            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)
                    Oracle.net.ns.Packet.receive(Packet.Java:300)
                    Oracle.net.ns.DataPacket.receive(DataPacket.Java:106)
                    Oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.Java:315)
                    Oracle.net.ns.NetInputStream.read(NetInputStream.Java:260)
                    Oracle.net.ns.NetInputStream.read(NetInputStream.Java:185)
                    Oracle.net.ns.NetInputStream.read(NetInputStream.Java:102)
                    Oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.Java:124)
                    Oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.Java:80)
                    Oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.Java:1137)
                    Oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.Java:290)
                    Oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.Java:192)
                    Oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.Java:380)
                    Oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.Java:760)
                    Oracle.jdbc.driver.T4CConnection.logon(T4CConnection.Java:401)
                    Oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.Java:546)
                    Oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.Java:236)
                    Oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.Java:32)
                    Oracle.jdbc.driver.OracleDriver.connect(OracleDriver.Java:521)
                    com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.Java:134)
                    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.Java:182)
                    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.Java:171)
                    com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.Java:137)
                    com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.Java:1014)
                    com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.Java:32)
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.Java:1810)
                    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:547)
            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)
                    Oracle.net.ns.Packet.receive(Packet.Java:300)
                    Oracle.net.ns.DataPacket.receive(DataPacket.Java:106)
                    Oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.Java:315)
                    Oracle.net.ns.NetInputStream.read(NetInputStream.Java:260)
                    Oracle.net.ns.NetInputStream.read(NetInputStream.Java:185)
                    Oracle.net.ns.NetInputStream.read(NetInputStream.Java:102)
                    Oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.Java:124)
                    Oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.Java:80)
                    Oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.Java:1137)
                    Oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.Java:290)
                    Oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.Java:192)
                    Oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.Java:380)
                    Oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.Java:760)
                    Oracle.jdbc.driver.T4CConnection.logon(T4CConnection.Java:401)
                    Oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.Java:546)
                    Oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.Java:236)
                    Oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.Java:32)
                    Oracle.jdbc.driver.OracleDriver.connect(OracleDriver.Java:521)
                    com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.Java:134)
                    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.Java:182)
                    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.Java:171)
                    com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.Java:137)
                    com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.Java:1014)
                    com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.Java:32)
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.Java:1810)
                    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)
                    Oracle.net.ns.Packet.receive(Packet.Java:300)
                    Oracle.net.ns.DataPacket.receive(DataPacket.Java:106)
                    Oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.Java:315)
                    Oracle.net.ns.NetInputStream.read(NetInputStream.Java:260)
                    Oracle.net.ns.NetInputStream.read(NetInputStream.Java:185)
                    Oracle.net.ns.NetInputStream.read(NetInputStream.Java:102)
                    Oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.Java:124)
                    Oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.Java:80)
                    Oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.Java:1137)
                    Oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.Java:290)
                    Oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.Java:192)
                    Oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.Java:380)
                    Oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.Java:760)
                    Oracle.jdbc.driver.T4CConnection.logon(T4CConnection.Java:401)
                    Oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.Java:546)
                    Oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.Java:236)
                    Oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.Java:32)
                    Oracle.jdbc.driver.OracleDriver.connect(OracleDriver.Java:521)
                    com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.Java:134)
                    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.Java:182)
                    com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.Java:171)
                    com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.Java:137)
                    com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.Java:1014)
                    com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.Java:32)
                    com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.Java:1810)
                    com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.Java:547)
13
eebbesen

Cela semble que vous avez déjà acquis une connexion du pool et ne la retournez pas à temps.

C3P0 détermine les "blocages apparents" lorsqu'une connexion est acquise mais n'est pas renvoyée au pool dans le délai imparti pour la détection d'interblocage.

Si vous rapprochez l'acquisition de la connexion de "l'action" et la renvoyez immédiatement au pool une fois le travail de la base de données terminé, ce message disparaîtra.

7
Thomas Weber

Cela réglera votre problème

ds.setMaxStatements(1000);
ds.setMaxStatementsPerConnection(100); (the maximum number of prepared statments your system can execute on a single connection)

découvrez: https://forum.hibernate.org/viewtopic.php?t=947246&highlight=apparent+deadlock+c3p0

N'oubliez pas de fermer vos déclarations après les avoir terminées !!

4
ChristiaanP

Bonjour mon ami juste pour commenter, j'ai eu le même cas. Je viens de configurer mon projet Spring-Hibernate Eclipse et de présenter la même exception. Il convient de noter que mon projet n'a toujours pas de requête.

J'ai résolu ce problème avec les étapes ci-dessous:

1) Projet propre: Projet -> Propre .... 2.) Projet de construction: Projet -> Projet de construction.

J'espère que cela fonctionne pour vous. 

0

J'ai eu le même problème (impossible à détecter) résolu en fermant correctement les instances Statement et Resultset (en quelque sorte laissées non fermées):

String SQL = "SELECT 1";
try {
    con = DriverManager.getConnection(Host, userName, userPassword);
    stmt = con.prepareStatement(SQL, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
    try {
        rs = stmt.executeQuery(SQL);
        try {
            rs.next();
            // ...
        } finally {
            rs.close();
        }
    } finally {
        stmt.close();
    }
} catch (SQLException ex) {
    Logger.getLogger(MyClass.class.getName()).log(Level.SEVERE, null, ex);
}
0
Zon

J'ai eu le même problème, mais la cause était un peu difficile à repérer car elle était causée par des ressources simultanées essayant d’acquérir une connexion en même temps.

Comme vous pouvez le lire si le pool n’a pas été initialisé, le code fourni pour l’initialiser en appelant une fonction de configuration.

public Connection getConnection() throws SQLException {
    if (mCPDS == null) {
        setupPool();
    }

    return mCPDS.getConnection();
}

Le problème était que beaucoup de ressources essayaient d’acquérir la connexion au début du programme, donc plus d’une instanciaient le pool causant votre problème après un certain temps.

La solution consistait simplement à déclarer la méthode synchronisée pour garder les autres ressources alors qu’une personne avait appelé la méthode et qu’elle restait toujours à instancier le pool, par exemple.

public synchronized Connection getConnection() throws SQLException {
    if (mCPDS == null) {
        setupPool();
    }

    return mCPDS.getConnection();
}

Cela peut être une erreur de conception pour ne pas utiliser un singleton, mais corrige le problème de manque de performances.

0
atzu

Je viens soudainement d'avoir le même problème: après avoir constaté que le blocage était présent uniquement lors du lancement de mon application en mode débogage (j'utilise IntelliJ) et que tout allait bien pour une exécution normale, j'ai commencé à le creuser.

J'ai finalement compris qu'un point d'arrêt bloquait la connexion: je ne sais pas pourquoi Intellij n'a pas "écouté" que l'application traversait ce point d'arrêt, mais a été pendu quelque part à cause d'un point d'arrêt, ce qui causait appartent impasse

Après avoir supprimé tous les points d'arrêt de mon projet, tout a recommencé sans heurts.

J'espère que cela aide quelqu'un

0
Leviand

@eebbesen, j'ai la même erreur que vous. J'utilise Tomcat version 9.0.6. J'ai hibernate core version 5.2.10, hibernate c3p0 version 3.6.3 dans mon projet maven. La mienne n'était pas une erreur d'authentification, mais plutôt parce que j'avais déjà changé le nom de mon ordinateur. Cela n'a pas eu d'effet immédiat sur Tomcat, mais lors du redémarrage de ma machine, lorsque j'ai tenté de relancer Tomcat via Eclipse (Oxygen 2), je ne pouvais plus démarrer Eclipse uniquement à cause du problème que vous avez soulevé.

J'ai googlé ceci et j'ai trouvé ce lien qui m'a mis au courant:

https://community.Oracle.com/thread/339825

où il est dit:

Commencez par vérifier si les services OracleServiceXE et OracleXETNSListener sont fonctionnement. Remplacez 127.0.0.1 dans l’url, par l’IP ou le nom de votre machine. Il doit correspondre à l'hôte déclaré dans le fichier tnsnames.ora.

Plus tard, il mentionne où trouver ce fichier tnsnames.ora, et pour moi, il était ici:

C:\oraclexe\app\Oracle\product\11.2.0\server\network\ADMIN

En regardant ce fichier tnsnames.ora, j'ai vu ceci:

XE =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(Host = MyMachineName-7)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = XE)
    )
  )

Mais j'avais récemment renommé ma machine MyMachineName-5. J'ai changé le 7 en 5 et sauvegardé le fichier. J'ai vérifié le fichier "listener.ora" dans ce répertoire et le même problème:

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
      (ADDRESS = (PROTOCOL = TCP)(Host = MyMachineName-7)(PORT = 1521))
    )
  )

J'ai changé le 7 en 5 et sauvegardé le fichier.

Ensuite, j'ai ouvert le Gestionnaire des tâches, cliqué sur l'onglet "Services" et examiné les services "Oracle". J'ai effectué un redémarrage sur: OracleXETNSListener, OracleXEClrAgent, OracleServiceXE. Je suis allé redémarrer Tomcat dans Eclipse, et cette fois, il y avait maintenant un problème.

Appendice:

J'ai aussi googlé ceci: 

https://community.Oracle.com/thread/2267906

Cela m'a amené à essayer:

1) Désactivation du pare-feu dans Windows Defender (pare-feu mcaffee déjà désactivé)

2) Démarrage de sqlplus pour m'assurer de pouvoir me connecter avec les informations d'identification que j'utilisais dans mon fichier hibernate: hibernate.cfg.xml

C:\oraclexe\app\Oracle\produit\11.2.0\serveur\bin\sqlplus.exe

3) Démarrage du raccourci sur le bureau vers Oracle Database 11g

Cela a échoué pour moi même après avoir résolu le problème du nom de la machine, ce que je dois encore examiner.

4) À l'aide de dbVisualizer, j'ai essayé d'établir une connexion avec Oracle. Cela n’a fonctionné qu’après que j’ai résolu le problème de nom de machine du fichier .ora: double-cliquez sur la connexion et cliquez sur le bouton "serveur ping".

0
Steve T

Mon commentaire sur la réponse https://stackoverflow.com/a/18192588/1019307 a reçu suffisamment de votes positifs pour suggérer que ce soit une réponse.

J'ai reçu cette erreur car je ne pouvais pas passer par le pare-feu du serveur de base de données. Vérifiez si c'est votre problème.

0
HankCa