java.sql.SQLException: Déjà fermé
Nous avons une webapp en production sur tomcat avec une base de données MySQL-end. Tout allait bien pendant un certain temps, puis tout à coup nous avons commencé à obtenir cette exception java.sql.SQLException: Already closed.
L'ensemble de la trace de la pile est:
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] Fetching JDBC Connection from DataSource
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] Returning JDBC Connection to DataSource
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] Could not close JDBC Connection
java.sql.SQLException: Already closed.
at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:114)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:191)
at org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection(DataSourceUtils.java:333)
at org.springframework.jdbc.datasource.DataSourceUtils.releaseConnection(DataSourceUtils.java:294)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:405)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:428)
at com.nokia.analytics.aws.aggregate.service.importer.DBInsert.truncateTable(DBInsert.java:135)
at com.blah.analytics.aggregate.service.importer.AggregateCollector.pullAndInsert(AggregateCollector.java:85)
at com.blah.analytics.aggregate.service.importer.AggregateCollector.call(AggregateCollector.java:96)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:679)
Nous utilisons org.apache.commons.dbcp.BasicDataSource
que notre source de données. J'ai cherché un peu, mais en vain.
Il ne se produit pas toujours, et il est donc très difficile à reproduire. Il semble un problème avec la connexion aux bases de la mutualisation. Quelque part, il a été suggéré de mettre cette param comme négatif. Actuellement, nous ne sommes pas la modification de ces paramètres (tous par défaut vals-les-bains).
Quelle approche doit-on suivre pour l'éviter?
EDIT:
Le code est dans (DBInsert.java)
133: String sql = "DELETE FROM "+tableName;
134: logger.debug(sql);
135: this.jdbcTemplate.execute(sql);
(133-135 sont ligne nos. qui sont spécifiés dans l'exception)
Ma source de données config:
<bean id="bisToolDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="${url}/blah_db?verifyServerCertificate=false&useSSL=true&requireSSL=true" />
<property name="username" value="${uname}" />
<property name="password" value="${passwd}" />
</bean>
- où est ton code?
- Je ne sais pas quelle en est la cause, mais c'est un bug,
Connection.close()
ne devrait pas lever une exception si déjà fermé: "l'Appel de la méthodeclose
sur unConnection
objet qui est déjà clôturée est un non-op"
Vous devez vous connecter pour publier un commentaire.
La cause de ce problème est la connexion n'est pas utilisé pendant une longue période, ajouter
testOnBorrow
etvalidationQuery
propriété à votre source de données de configuration de votre application fonctionnera très bien.Bonne chance:)
En tant qu'utilisateur NobodyElse souligné, le problème était lié à la connexion de la mutualisation. J'ai été en utilisant
org.apache.commons.dbcp.BasicDataSource
tant que source de données. La nature de la demande est telle qu'il n'y est poussée des connexions à un certain moment fixe dans la journée et pas de connexions à tous pour l'ensemble de la journée. Donc, pour cette raison connexions dans le pool devenaient obsolètes et lors de la prochaine journée de l'application a essayé de se connecter à la DB, nous avons été faire de cette exception.Il y a en gros deux solutions à cela:
L'un l'a souligné NobodyElse, c'est-à utiliser
testOnBorrow
; les détails peuvent être trouvés iciL'autre solution (que j'ai employées pour notre application) est de désactiver la mise en commun complètement. Note de le faire uniquement lorsque l'application n'est pas DB intensive (ce qui était vrai dans notre cas). Donc je suis passé à
org.springframework.jdbc.datasource.DriverManagerDataSource
. La config pour qui il semble fonctionner correctement est: