web-dev-qa-db-fra.com

Quels sont les paramètres C3P0 requis pour la mise en veille prolongée afin d'éviter les blocages

J'utilise Hibernate avec MySQL 5.1.30.

J'ai les prochaines bibliothèques:

  • c3p0-0.0.1.2.jar
  • mysql-connector-Java-5.0.3-bin.jar
  • hibernate3.jar

J'utilise un hibernate.cfg.xml pour la configuration:

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.gjt.mm.mysql.Driver</property> 

        <property name="connection.url">jdbc:mysql://localhost/fooDatatbase</property>
    <property name="connection.username">foo</property>
    <property name="connection.password">foo123</property>

        <!-- Use the C3P0 connection pool provider -->
    <property name="hibernate.c3p0.min_size">5</property>
    <property name="hibernate.c3p0.max_size">20</property>
    <property name="hibernate.c3p0.timeout">300</property>
    <property name="hibernate.c3p0.max_statements">50</property>
    <property name="hibernate.c3p0.idle_test_periods">3000</property>       

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <mapping resource="databaselayer/mail/Mail.hbm.xml"/>
        <mapping resource="databaselayer/courses/Course.hbm.xml"/>
        <mapping resource="databaselayer/price/Price.hbm.xml"/>        
        <mapping resource="databaselayer/contact/Contact.hbm.xml"/>
        <mapping resource="databaselayer/artists/Musician.hbm.xml"/>
        <mapping resource="databaselayer/concerts/Concert.hbm.xml"/>     
        <mapping resource="databaselayer/welcome/Welcome.hbm.xml"/>
        <mapping resource="databaselayer/information/Information.hbm.xml"/>                             
    </session-factory>
</hibernate-configuration>

Dans le livre Persistance Java avec mise en veille prolongée , les options de configuration de c3p0 sont expliquées:

  • hibernate.c3p0.min_size Il s'agit du nombre minimum de connexions JDBC que C3P0 garde toujours prêt
  • hibernate.c3p0.max_size Il s'agit du nombre maximal de connexions dans le pool. Une exception est levée lors de l'exécution si ce nombre est épuisé.
  • hibernate.c3p0.timeout Vous spécifiez le délai d'expiration (dans ce cas, 300 secondes) après lequel une connexion inactive est supprimée du pool).
  • hibernate.c3p0.max_statements Nombre maximal d'instructions qui seront mises en cache. La mise en cache des instructions préparées est essentielle pour de meilleures performances avec Hibernate.
  • hibernate.c3p0.idle_test_periods Il s'agit du temps d'inactivité en secondes avant qu'une connexion ne soit automatiquement validée.

J'utilise Java 1.5.0_09 et Tomcat 6.0 . J'ai trois applications déployées dans Tomcat. Chacune utilise hibernate avec un fichier de configuration presque équivalent à celui montré ci-dessus (seuls le nom d'utilisateur, le nom de la base de données, le mot de passe et le mappage résorbe le changement).

Malheureusement avec les paramètres ci-dessus, après quelques heures de fonctionnement, j'obtiens de mauvaises erreurs de blocage qui finissent par tuer Tomcat.

Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@2437d -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1dc5cb7 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@9cd2ef -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4af355 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:07 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run
WARNING: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@1275fcb -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
Jan 22, 2009 3:29:35 PM com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector run

Cela semble être une erreur que plusieurs personnes ont déjà eue. J'ai modifié mes paramètres en essayant de suivre la solution de contournement décrite ici http://forum.hibernate.org/viewtopic.php?p=2386237 en:

<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.min_size">0</property>
<property name="hibernate.c3p0.max_size">48</property>
<property name="hibernate.c3p0.timeout">0</property>
<property name="hibernate.c3p0.max_statements">0</property>

Avec les nouveaux paramètres, je n'obtiens pas de blocages, mais j'obtiens:

WARNING: SQL Error: 0, SQLState: 08S01
Jan 24, 2009 5:53:37 AM org.hibernate.util.JDBCExceptionReporter logExceptions
SEVERE: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

Java.io.EOFException

STACKTRACE:

Java.io.EOFException
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.Java:1913)

Quelqu'un sait-il ce que je fais mal et comment configurer correctement c3p0?

46
Sergio del Amo

En fait, c'est probablement trop tard, mais le problème est assez simple: hibernate.c3p0.idle_test_periods ne doit pas être supérieur à hibernate.c3p0.timeout ou les connexions fermées par la base de données ne seront pas correctement détectées.

De plus, les avertissements de détection de blocage semblent qu'une partie de votre code ne renvoie pas correctement les connexions au pool (c'est-à-dire session.close ())

Les exceptions MysqlIO se produisent lorsque votre application est inactive et MySQL ferme la connexion sur le serveur. Maintenant, si C3P0 ne vérifie pas correctement si une connexion est toujours réellement connectée, vous obtenez les EOFExceptions.

J'espère que cela pourrait être utile.

48
Thomas Weber

Il n'y a pas de réponse définitive à cette question, car elle change d'une application à l'autre en fonction du modèle d'utilisation et de charge.

Le premier point est de se référer au lien https://www.hibernate.org/214.html , car il semble que vous l'ayez fait et que vous ayez avancé. voici quelques conseils;

  • numHelperThreads: threads d'assistance qui ne contiennent pas de verrous rivaux. Répartir ces opérations sur plusieurs threads
  • maxStatements: taille du cache global PreparedStatement de c3p0.
  • maxStatementsPerConnection: Le nombre de PreparedStatements c3p0 sera mis en cache pour une seule connexion groupée.
  • maxAdministrativeTaskTime: paramètre qui force un appel à la méthode interrupt () du thread de tâche si une tâche dépasse une limite de temps définie

Les trois premiers paramètres peuvent améliorer ou réduire les performances en fonction de la valeur définie, tandis que le quatrième paramètre peut interrompre le thread après la limite définie et donner une modification à exécuter sur un autre thread.

Valeurs approximatives

  • numHelperThreads = 6
  • maxStatements = 100
  • maxStatementsPerConnection = 12
  • maxAdministrativeTaskTime = besoin de suffisamment de temps pour que la requête lourde puisse s'exécuter en production

maxStatements et maxStatementsPerConnection doivent être testés pendant quelques mois, car peu de points de publication sont bloqués à cause de ces paramètres.

Se référer également à ces liens sera utile;

8
Varun Mehta

Les hibernate.c3p0.idle_test_periods doivent être inférieurs à h * ibernate.c3p0.timeout * car le premier est juste une valeur de temps où hibernate vérifie les connexions inactives et essaie de la fermer.

Pendant ce temps, la seconde est juste combien de temps une connexion doit être éjectée.

Si idle_test_periods est plus grand que le paramètre timeout que hibernate, recherchez tout ce qui est nul ou inexistant dans le système. Au moins, j'ai compris de cette façon.

3
user2935659
    <property name="hibernate.c3p0.timeout">300</property>     
    <property name="hibernate.c3p0.idle_test_periods">3000</property>       

la valeur idle_test_period doit être inférieure à la valeur de temporisation.

1
jprism

C'est une assez ancienne version de Connector/J. Pour vous assurer que vous ne luttez pas contre un bogue connu et corrigé, je commencerais par obtenir le plus récent (5.0.8):

http://dev.mysql.com/downloads/connector/j/5.0.html

Ce EOFException de MysqlIO est un peu suspect. Sous une utilisation normale/sans bug, vous ne devriez jamais obtenir d'erreurs de cette couche.

1
Trenton

Les trois applications partagent-elles le même pool de connexions ou chacune obtient-elle la sienne? Je recommanderais ce dernier.

0
duffymo