2017-09-06 3 views
0

J'ai rencontré un problème lors de la configuration des paramètres c3p0. Le senario est: J'ai un projet Java qui commencera à 3h00 du matin tous les jours et ensuite se connecter à la base de données pour faire quelque chose. Parfois, la base de données peut être en panne à ce moment-là et peut être récupérée après 2 ou 3 heures.
Je dois donc faire en sorte que le programme essaie de reconnecter la base de données dans un intervalle de temps spécifique pour voir si la base de données est correcte, jusqu'à ce qu'elle puisse se connecter avec succès à la base de données. J'ai essayé de configurer le c3p0 pour reconnecter la base de données infiniment jusqu'à la réussite, mais il semble coincé dans une impasse. Voici mes paramètres c3p0. J'utilise c3p0 v0.9.1 avec hibernate dans Spring framework, la base de données est DB2.C3p0 n'a pas réussi à reconnecter la base de données lorsque la base de données est hors service

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" > 
    <property name="driverClass" value="${jdbc.driverClassName}"/> 
    <property name="jdbcUrl" value="${jdbc.url}"/> 
    <property name="user" value="root"/> 
    <property name="password" value="root"/> 

    <property name="acquireRetryAttempts" value="0"/> 

    <property name="acquireRetryDelay" value="10000"/> 

    <property name="maxIdleTime"value="60"/> 
    <property name="minPoolSize" value="5" /> 
    <property name="maxPoolSize" value="200"/> 
    <property name="idleConnectionTestPeriod" value="30" /> 
    <property name="preferredTestQuery" value="values(1)" /> 
</bean> 

Quand je lance le programme, il a échoué et le journal d'erreur est indiqué ci-dessous:

[WARN]: com[email protected]21eb3f -- APPARENT DEADLOCK!!! 
Creating emergency threads for unassigned pending tasks! 
[WARN]: com[email protected]21eb3f -- APPARENT DEADLOCK!!! 
Complete Status: 
Managed Threads: 3 
Active Threads: 3 
Active Tasks: 
    [email protected]d (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0) 
    [email protected]c (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1) 
    [email protected]3 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2) 
Pending Tasks: 
    [email protected]4 
    [email protected]0 
    [email protected] 
    [email protected]2 
    [email protected] 
    [email protected] 
    [email protected] 
Pool thread stack traces: 
    ... 
[WARN] [2017-09-04 ThreadPoolAsynchronousRunner.processReplacedThreads() ] Task [email protected] 
(in deadlocked PoolThread) failed to complete in maximum time 60000ms. Trying interrupt(). 
[WARN] [2017-09-04 ThreadPoolAsynchronousRunner.processReplacedThreads() ] Task [email protected] 
(in deadlocked PoolThread) failed to complete in maximum time 60000ms. Trying interrupt(). 
[WARN] [2017-09-04 ThreadPoolAsynchronousRunner.processReplacedThreads() ] Task [email protected] 
(in deadlocked PoolThread) failed to complete in maximum time 60000ms. Trying interrupt(). 

[WARN] [2017-09-04 BasicResourcePool$AcquireTask.run()] [email protected] -- Thread unexpectedly interrupted 
while performing an acquisition attempt. 
java.lang.InterruptedException: sleep interrupted 
    at java.lang.Thread.sleep(Native Method) 
    at com.mchange.v2.resourcepol.BasicResourcePool$AcquireTask.run (BasicResourcePool.java:1805) 
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 
[WARN] [2017-09-04 BasicResourcePool$AcquireTask.run()] [email protected] -- Thread unexpectedly interrupted 
while performing an acquisition attempt. 
java.lang.InterruptedException: sleep interrupted 
    at java.lang.Thread.sleep(Native Method) 
    at com.mchange.v2.resourcepol.BasicResourcePool$AcquireTask.run (BasicResourcePool.java:1805) 
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 
[WARN] [2017-09-04 BasicResourcePool$AcquireTask.run()] [email protected] -- Thread unexpectedly interrupted 
while performing an acquisition attempt. 
java.lang.InterruptedException: sleep interrupted 
    at java.lang.Thread.sleep(Native Method) 
    at com.mchange.v2.resourcepol.BasicResourcePool$AcquireTask.run (BasicResourcePool.java:1805) 
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547) 

Pourriez-vous s'il vous plaît aider à corriger mes si les paramètres a quelque chose de mal? Merci d'avance!

+0

Comment cette 'application' a-t-elle démarré? cron? –

+0

@Scary Oui, c'est. – cmjauto

+0

alors pouvez-vous essayer d'utiliser un outil, par exemple. db cli client, pour tester si la base de données est en place avant d'essayer de démarrer votre application et le mettre dans votre script de démarrage de l'application –

Répondre

0

D'abord, vous ne devriez pas utiliser c3p0-0.9.1. C'est ancien. La version actuelle est 0.9.5.2.

Le problème ici est que, lorsque votre base de données est en panne, les tentatives de connexion n'échouent pas avec une exception, elles sont suspendues. Le pool de threads de c3p0 se remplit donc de tentatives d'acquisition de connexions qui ne réussissent pas et échouent, mais se bloquent indéfiniment. Une fois que le pool Thread est complètement saturé et bloqué pendant un moment, c3p0 déclare un DEADLOCK APPARENT et vous voyez ce que vous voyez. La meilleure chose à faire est de réparer tout ce qui est défectueux dans votre réseau ou votre serveur qui provoque des tentatives de connexion à la base de données pour bloquer plutôt que réussir ou échouer. Si vous pouvez résoudre ce problème, votre problème disparaîtra probablement.

Si vous ne pouvez pas résoudre ce problème, vous pouvez peut-être contourner le problème avec un paramètre c3p0, maxAdministrativeTaskTime. Si vous définissez ceci, après le nombre de secondes que vous définissez, c3p0 considèrera que toutes les tâches suspendues (comme vos tentatives d'acquisition Connection) seront brisées et tentera de forcer leur échec en appelant interrupt() sur les Threads que les tâches ont bloquées. Si vous êtes chanceux, vos tâches d'acquisition gelées échoueront avec un InterruptedException et la vie continuera.

Si vous utilisez maxAdministrativeTaskTime, vous devrez définir une valeur significativement plus longue que la connexion à votre base de données pourrait raisonnablement exiger (tant que le SGBD est disponible et disponible). Vous aurez probablement aussi besoin d'augmenter numHelperThreads par rapport à sa valeur par défaut de 3, de sorte que les tâches d'acquisition non infinies mais toujours léthargiques aient plus de Threads à jouer avant de saturer tout le pool de threads et de provoquer un blocage.

+0

Merci pour l'explication détaillée, je vais essayer une nouvelle version avec votre proposition. – cmjauto