Reproduire com.mysql.jdbc.exception.jdbc4.CommunicationsException avec une configuration de printemps, hibernation et C3P0
j'ai eu cette erreur du code de production:
com.mysql.jdbc.exception.jdbc4.CommunicationsException: Le dernier paquet reçu avec succès du serveur était de 36940 secondes il ya.Le dernier paquet envoyé avec succès il y a 36940 secondes, qui est plus long que le serveur valeur configurée de 'wait_timeout'. Vous devriez expirant et / ou tester la validité de la connexion avant utilisation dans votre application, l'augmentation du serveur configuré valeurs pour les délais du client, ou en utilisant la propriété Connector / J connection 'autoReconnect=true' pour éviter cela problème.
et maintenant j'essaie de reproduire le problème localement et de le corriger. J'ai configuré le contexte du ressort comme suit:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" p:driverClass="com.mysql.jdbc.Driver"
p:jdbcUrl="jdbc:mysql://localhost:3306/test?userUnicode=yes&characterEncoding=UTF-8&"
p:idleConnectionTestPeriod="120" p:initialPoolSize="1" p:maxIdleTime="1800"
p:maxPoolSize="1" p:minPoolSize="1" p:checkoutTimeout="1000"
/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<value>
hibernate.connection.provider_class = org.hibernate.connection.C3P0ConnectionProvider
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.default_schema=platform_server_original
hibernate.show_sql=false
</value>
</property>
<property name="mappingResources">
<list>
<value>sometables.hbm.xml</value>
</list>
</property>
</bean>
puis j'ai mis mon mysql wait_timeout à 10 secondes, puis j'ai lancé mon test, qui consiste essentiellement à ouvrir une connexion, faire une requête, la fermer, de sorte qu'elle retourne à la piscine, puis le sommeil le fil pendant 15 secondes, puis l'ouvrir de nouveau, et faire une requête, donc il va se casser. Cependant, j'ai eu une erreur similaire seulement:
com.mysql.jdbc.exception.jdbc4.CommunicationsException: Communication link failure
dernier paquet envoyé au serveur était 16 Mlle ago.
alors je me demande si ces deux erreurs sont identiques, ou si elles sont différentes? J'ai fait quelques recherches, et il il semble que les deux erreurs aient abouti à la même solution: en utilisant une propriété "testConnectionOnCheckout=true". Toutefois, selon c3p0 doc, il s'agit d'un contrôle très coûteux. Il conseille l'utilisation de "idleConnectionTestPeriod", mais je mets déjà cela à 120 secondes. Quelle valeur dois-je l'utiliser afin de pouvoir vérifier la connexion inactive?
donc je demande deux choses: 1. Comment puis-je reproduire l'erreur que j'ai eue dans le code de production? 2. comment puis-je résoudre ce problème?
Merci!
3 réponses
J'ai eu des problèmes similaires avec MySQL et un pool de connexion. Le problème est que vous dites au pool de connexion qu'un temps mort est de 30 minutes, mais que la base de données coupe la connexion après 10 Secondes. Puisque votre période de contrôle de connexion au ralenti est de 120 secondes, il laisse un peu moins de 110 secondes pour que la piscine utilise une connexion brisée!
j'utiliserais les réglages suivants pour la production:
MySQL:
wait_timeout=75
C3P0:
maxIdleTime=60
idleConnectionTestPeriod=55
pour reproduire votre erreur, définissez votre délai de connexion dans vos propriétés MySQL à une valeur très faible, c'est-à-dire 2 ms, et lancez une requête connue pour avoir un long temps de traitement. Vous pouvez définir la propriété timeout dans la chaîne de connexion MySQL ou via une propriété si vous utilisez des fichiers de propriétés pour configurer votre connexion JDBC. Vous pouvez consulter les Javadocs sur votre jaxax spécifique.SQL.DataSource connection et les documents MySQL pour les détails sur la façon de faire ceci.
Fei-pourrait être une de plusieurs choses, ne peut pas vraiment dire basé sur l'information affichée jusqu'ici.
suggérez D'ajouter les numéros de version MySQL/Spring/Hibernate/C3PO/JDBC à votre question, au cas où il y aurait un problème connu.
le message d'erreur de production est commun, avec de nombreuses causes possibles. Quelques pistes pour vous:
-
L'erreur de production peut indiquer que votre application est pas libération d'une connexion de retour à l' piscine lorsqu'il est fait avec, la prévention c3p0 de vérification. (Le c3p0 inactif contrôles ne peuvent être appliquées à connexions non vérifiées.)
-
vérifier que c3p0 fonctionne vraiment (vous pouvez utiliser "vanille" les connexions si non). Dans votre test, si vous définissez (par exemple) MySql wait_timeout=10, l'application thread sommeil=35, et idleConnectionTestPeriod = 30, si la mise en commun fonctionne, l'exception devraient disparaître.
-
Sur la dépense de l'inactivité des contrôles: envisager de ne pas utiliser la valeur par défaut getTables() - peut-être mis preferredTestQuery à quelque chose de pas cher(-er) 'SELECT 1" peut-être pour MySQL?