2009-04-08 5 views
15

MySQL semble avoir un délai de 8 heures sur ses connexions. J'utilise plusieurs WAR dans Tomcat en utilisant Hibernate pour ORM. Au bout de 8 heures (c'est-à-dire pendant la nuit), j'ai des tuyaux cassés quand il prend une connexion inactive.Hibernate, C3P0, Mysql - Broken Pipe

J'ai déjà suivi le code et j'ai doublement vérifié que je validais ou annulais toutes les transactions.

Voici mon hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
<session-factory> 
    <property name="hibernate.bytecode.use_reflection_optimizer">false</property> 
    <property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property> 
    <property name="hibernate.connection.password"></property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost/test</property> 
    <property name="hibernate.connection.username">root</property> 
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> 
    <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property> 
    <property name="hibernate.current_session_context_class">thread</property> 
    <!--property name="hibernate.show_sql">true</property> 
    <property name="hibernate.format_sql">true</property--> 

    <property name="c3p0.min_size">3</property> 
    <property name="c3p0.max_size">5</property> 
    <property name="c3p0.timeout">1800</property> 
    <property name="c3p0.preferredTestQuery">SELECT 1</property> 
    <property name="c3p0.testConnectionOnCheckout">true</property> 
    <property name="c3p0.idle_test_period">100</property> <!-- seconds --> 

    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 
    <property name="cache.use_query_cache">false</property> 
    <property name="cache.use_minimal_puts">false</property> 
    <property name="max_fetch_depth">10</property> 

    <property name="hibernate.hbm2ddl.auto">update</property> 

    <!-- classes removed --> 

</session-factory> 

Le paramètre que je pensais aurait fixé ce fut le c3p0.idle_test_period - Sa valeur par défaut 0. Cependant, nous avons encore la question de Broken Pipe après 8 heures de fonctionnement. Bien qu'il existe plusieurs index de messages via Google, aucun n'arrive à une réponse satisfaisante.

Répondre

23

Il se révèle que je manque une ligne clé qui a permis c3p0 (les paramètres de c3p0 je peaufinage étaient sans effet parce que Hibernate utilisait il est construit dans la piscine de connexion - qui met en garde appropriée n'est pas adapté à la production). Dans Hibernate 2.x, la définition de la propriété hibernate.c3p0.max_size a permis le regroupement de connexions c3p0. Cependant, dans 3.x vous devez spécifier la propriété suivante -

<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> 

De plus, voici mes paramètres de configuration finale -

<property name="hibernate.c3p0.min_size">3</property> 
<property name="hibernate.c3p0.max_size">5</property> 
<property name="hibernate.c3p0.timeout">1800</property> 
<property name="hibernate.c3p0.idle_test_period">100</property> <!-- seconds --> 

Il est regrettable que les deux Hibernate et C3P0 ont la documentation abyssal Ceci concerne.

+0

Merci, cela m'a aidé. Je suis d'accord avec le commentaire de la documentation. Pire encore, la documentation c3p0 vous conseille d'utiliser c3p0.properties pour tous les autres sauf les 5 ci-dessus, mais cela ne fonctionne pas. Cela ne fonctionne que lorsque vous spécifiez dans le fichier persistence.xml sans le préfixe hibernate (comme vous l'avez fait dans votre fichier cfg.xml d'origine) – Sun

+0

Cela m'a aidé aussi ... Je suis d'accord sur la chose de la documentation :). Cela pourrait être un peu plus simple dans leur documentation. – Polaris878

+0

Si vous avez utilisé la config xml pour CombPooledDataSource, la propriété est "idleConnectionTestPeriod" dont vous avez besoin. –

2

Il y a deux choses qui se passent ici. Vous devriez lire this article pour plus de détails, mais les plats à emporter sont:

  1. Vous pouvez régler le paramètre MySQL wait_timeout à quelque chose de plus de 8 heures, si on le souhaite.
  2. Les paramètres Hibernate doivent inclure "hibernate". avant le "c3p0", par ex. hibernate.c3p0.idle_test_period au lieu de simplement c3p0.idle_test_period
+0

Je vais essayer d'ajouter le préfixe hibernate aujourd'hui. Je ne pense pas que l'extension de MySQL wait_timeout aiderait ... Je retarderais juste l'erreur de tuyau cassé. – Mark

1

J'ai plusieurs problèmes - - C3P0ConnectionProvider n'a pas été trouvé - je le résoudre en utilisant la version c3p0 veille prolongée

 <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>3.5.6-Final</version> 
    </dependency> 
      <!-- c3p0 --> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-c3p0</artifactId> 
     <version>3.3.1.GA</version> 
    </dependency> 

- J'ai que wait_timeout question sur MySQL. D'abord, j'ai défini /etc/my.cnf wait_timeout = 10 puis j'ai changé la valeur du délai d'inactivité à une valeur inférieure à la valeur wait_timeout Cela a résolu mon problème.

<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" /> <property name="hibernate.c3p0.acquire_increment" value="1" /> 
     <property name="hibernate.c3p0.idle_test_period" value="28690"/> 
     <property name="hibernate.c3p0.timeout" value="1800" /> 
     <property name="hibernate.c3p0.max_size" value="5" /> 
     <property name="hibernate.c3p0.min_size" value="3" /> 
     <property name="hibernate.c3p0.max_statement" value="50" /> 
     <property name="hibernate.c3p0.preferredTestQuery" value="select 1;"/> 
2

Ceci est une solution quand vous avez un tuyau cassé en raison de la combinaison de wait_timeout de tomcat = 28800 sec (8h) et MaxIdleTime = 0 dans c3p0:

J'ai changé la tomcat locale wait_timeout via mon Fichier .ini à 120sec (2 min).Et je posai les éléments suivants:
MaxIdleTime = 100
idleConnectionTestPeriod = 0 (même par défaut/comme si elle n'existait pas)
autre:
acquireIncrement = 2
MinPoolSize = 2
MaxPoolSize = 5
maxIdleTimeExcessConnections = 10

Je n'ai eu aucun problème avec cette configuration.

Je n'avais pas besoin d'utiliser idleConnectionTestPeriod! Si wait_timeout de tomcat est 28800 sec, et que maxIdleTime vaut 25200, cela signifie que c3p0 fermera la connexion inactive à 3600sec (1h) plus tôt, avant que tomcat ne lance une exception de "pipe cassée". N'est-ce pas ?!

Comme vous pouvez le voir, je n'ai aucun problème à fournir uniquement maxIdleTime.

Malheureusement, ceux-ci:
maxIdleTime
idleConnectionTestPeriod
configuring_connection_testing
testConnectionOnCheckin
n'expliquent pas trop les cas de coin.

Et, d'ailleurs, voici comment ouvrir le fichier my.ini de tomcat avec Notepad ++: http://drupal.org/node/32715#comment-4907440

Cheers,
Despot

1

Je recevais le même problème et il a fallu du temps pour comprendre la solution. J'utilise Hibernate 4.0.1 et mysql 5.1 (pas de framework à ressort) et j'étais confronté au problème. Assurez-vous d'abord que vous avez bien configuré les bocaux c3p0 qui sont essentiels.

J'ai utilisé ces propriétés dans hibernate.cfg.xml

<property name="hibernate.c3p0.validate">true</property> 
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property> 
<property name="hibernate.c3p0.min_size">5</property> 
<property name="hibernate.c3p0.max_size">20</property> 
<property name="hibernate.c3p0.max_statements">50</property> 
<property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property> 
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property> 
<property name="hibernate.c3p0.idle_test_period">10</property> 
<property name="hibernate.c3p0.acquireRetryAttempts">5</property> 
<property name="hibernate.c3p0.acquireRetryDelay">200</property> 
<property name="hibernate.c3p0.timeout">40</property> 

Mais il est inutile parce que C3P0 prenait encore les propriétés par défaut pas les propriétés que je mets en hibernate.cfg.xml, Vous pouvez vérifiez-le dans les journaux. Donc, j'ai cherché de nombreux sites Web pour la bonne solution et finalement je suis arrivé avec cela. supprimez les propriétés C3p0 dans cfg.xml et créez c3p0-config.xml dans le chemin racine (avec cfg.xml) et définissez les propriétés comme suit.

<c3p0-config> 
<default-config> 
<property name="automaticTestTable">con_test</property> 
<property name="checkoutTimeout">40</property> 
<property name="idleConnectionTestPeriod">10</property> 
<property name="initialPoolSize">10</property> 
<property name="maxPoolSize">20</property> 
<property name="minPoolSize">5</property> 
<property name="maxStatements">50</property> 
<property name="preferredTestQuery">SELECT 1;</property> 
<property name="acquireRetryAttempts">5</property> 
<property name="acquireRetryDelay">200</property> 
<property name="maxIdleTime">30</property> 
</default-config> 
</c3p0-config> 

mais si vous exécutez, ORM prend la connexion jdbc mais pas pool de connexion C3P0 parce que nous devrions ajouter ces propriétés dans hibernate.cfg.xml

<property name="hibernate.c3p0.validate">true</property> 

<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property> 

maintenant tout fonctionne bien (au moins il a bien fonctionné pour moi) et la question est résolue.

vérifiez les points suivants pour les références.

http://www.mchange.com/projects/c3p0/index.html#configuring_connection_testing

https://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool

J'espère que cela résout votre problème.

Questions connexes