2013-05-02 14 views
5

Wir haben eine Webapp läuft in der Produktion auf Tomcat mit einem MySQL-Back-End. Alles war für einige Zeit in Ordnung, dann plötzlich haben wir begonnen, diese Ausnahme immer java.sql.SQLException: Already closed.java.sql.SQLException: Bereits geschlossen

Der gesamte Stack-Trace ist:

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) 

Wir org.apache.commons.dbcp.BasicDataSource als unsere Datenquelle verwenden. Ich suchte ziemlich viel, aber ohne Erfolg. Es tritt nicht immer auf und ist daher sehr schwer zu reproduzieren. Es scheint ein Problem mit dem Db-Verbindungs-Pooling zu sein. Irgendwo wurde vorgeschlagen, this param als negativ zu setzen. Derzeit ändern wir diese Parameter nicht (alle haben Standardwerte).

Welchen Ansatz sollten wir befolgen, um dies zu vermeiden?

EDIT:

der entsprechende Code ist in (DBInsert.java)

133: String sql = "DELETE FROM "+tableName;

134: logger.debug(sql);

135: this.jdbcTemplate.execute(sql);

(133-135 sind Zeilennummern, die in der Ausnahme angegeben sind)

Meine Datenquelle 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&amp;useSSL=true&amp;requireSSL=true" /> 
     <property name="username" value="${uname}" /> 
     <property name="password" value="${passwd}" /> 
    </bean> 
+0

wo ist dein Code? –

+0

Ich weiß nicht, was es verursacht, aber es ist ein Fehler, ['Connection.close()'] (http://docs.oracle.com/javase/7/docs/api/java/sql/Connection. html # close()) sollte keine Ausnahme auslösen, wenn sie bereits geschlossen ist: _ "Die Methode' close' auf einem 'Connection'-Objekt aufzurufen, das bereits geschlossen ist, ist ein No-Op" _ –

Antwort

13

Die Ursache dieses Problems ist Verbindung nicht in einer langen Zeit verwendet wird, testOnBorrow und validationQuery Eigenschaft zu Ihrer Datenquelle Konfiguration fügen Sie dann Ihre Anwendung funktionieren.
Viel Glück :)

+0

+1 Sie haben absolut Recht Problem. Ich hatte bereits herausgefunden, dass das Problem mit dem Verbindungs-Pooling und dem Verbindungs-Pooling zusammenhing. –

+0

Nun, der einzige Grund, warum ich nicht akzeptiert habe, ist, dass ich den von Ihnen vorgeschlagenen Ansatz nicht ausprobiert habe ... –

+0

@HarshalWaghmare, möchte fragen, was meinst du mit ausgeschaltetem Verbindungspooling? Meine Anwendung läuft unter IBM WAS und verwendet db2 als Datenbank. Meistens sehe ich, dass die Einstellung für den Verbindungspool die maximale Verbindung und die minimale Verbindungsgröße betrifft. Aber nicht über die Einstellung deaktivieren, kann beraten werden? –

6

als Benutzer NobodyElse wies darauf hin, wurde das Problem Verbindungspooling Zusammenhang stehen. Ich benutzte org.apache.commons.dbcp.BasicDataSource als Datenquelle. Die Art der Anwendung ist so beschaffen, dass zu bestimmten Zeiten am Tag Verbindungen entstehen und für den ganzen Tag gar keine Verbindungen bestehen. Aus diesem Grund wurden Verbindungen im Pool schal und als am nächsten Tag versucht wurde, eine Verbindung zur Datenbank herzustellen, erhielten wir diese Ausnahme.

Es gibt grundsätzlich zwei Lösungen dazu: Der eine wies darauf hin, durch NobodyElse, das heißt testOnBorrow verwenden; Details finden Sie here

Die andere Lösung (die ich für unsere App verwendet) ist, Pooling vollständig auszuschalten. Beachten Sie dies nur, wenn die Anwendung nicht DB-intensiv ist (was in unserem Fall der Fall war). Also wechselte ich zu org.springframework.jdbc.datasource.DriverManagerDataSource. Die Konfiguration, für die es scheint zu funktionieren, ist:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
     <property name="url" 
      value="${url}/blah_db?verifyServerCertificate=false&amp;useSSL=true&amp;requireSSL=true" /> 
     <property name="username" value="${uname}" /> 
     <property name="password" value="${passwd}" /> 
</bean> 
+0

FYI .... "DriverManagerDataSource" ist nicht wirklich Verbindungspool. http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/jdbc/datasource/DriverManagerDataSource.html – kosa

Verwandte Themen