2013-05-02 13 views
5

Mamy webappa działającego na serwerze tomcat z back-endem MySQL. Wszystko było w porządku na jakiś czas, a potem nagle zaczął się ten wyjątek java.sql.SQLException: Already closed.Wyjaśnienie java.sql.SQLException: Już zamknięte

Cały ślad stosu jest:

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) 

Używamy org.apache.commons.dbcp.BasicDataSource jako naszego źródła danych. Szukałem trochę, ale bezskutecznie. Nie występuje zawsze i dlatego jest bardzo trudny do odtworzenia. Wydaje się, że problem z puli połączeń db. Gdzieś zasugerowano, aby ustawić parametr this jako negatywny. Obecnie nie zmieniamy tych parametrów (wszystkie mają domyślne vals).

Jakie podejście powinniśmy zastosować, aby tego uniknąć?

Edycja:

Odpowiedni kod jest (DBInsert.java)

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

134: logger.debug(sql);

135: this.jdbcTemplate.execute(sql);

(133-135 są numery linii, które są określone w wyjątku)

Moje źródła danych 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

gdzie jest twój kod? –

+0

Nie wiem, co powoduje, ale jest to błąd, ['Connection.close()'] (http://docs.oracle.com/javase/7/docs/api/java/sql/Connection. html # close()) nie powinien wyrzucać wyjątku, jeśli jest już zamknięty: _ "Wywołanie metody" zamknij "na obiekcie" Połączenie ", który jest już zamknięty, nie jest opcją" _ –

Odpowiedz

13

Przyczyną tego problemu jest połączenie nie jest używany przez długi czas, należy dodać testOnBorrow i validationQuery właściwość konfiguracji źródła danych, a następnie aplikacja będzie działać prawidłowo.
Powodzenia :)

+0

+1 Masz absolutnie rację w wykrywaniu problem. Zorientowałem się, że problem związany jest z połączeniem puli i wyłączeniem puli połączeń. –

+0

Cóż, jedynym powodem, dla którego nie zaakceptowałem, było to, że nie wypróbowałem sugerowanego przez ciebie podejścia ... –

+0

@Harshal Waghmare, chciałbyś zapytać co masz na myśli przez wyłączenie puli połączeń? Moja aplikacja działa w środowisku IBM WAS i używa db2 jako bazy danych. Głównie to, co widzę w ustawieniach puli połączeń, może dotyczyć maksymalnego połączenia i minimalnego rozmiaru połączenia. Ale nie rozumiem ustawień wyłączonych, czy mogę doradzić? –

6

Jako użytkownik NobodyElse wskazał, problem był związany z puli połączeń. Używałem org.apache.commons.dbcp.BasicDataSource jako źródła danych. Charakter aplikacji jest taki, że dochodzi do zerwania połączeń w określonym czasie w ciągu dnia i braku połączeń w ogóle przez cały dzień. Więc z powodu tych połączeń w puli zanikały i kiedy aplikacja następnego dnia próbował połączyć się z DB, otrzymywaliśmy ten wyjątek.

Istnieją zasadniczo dwa rozwiązania to: Ten wskazał NobodyElse, że jest użycie testOnBorrow; szczegóły można znaleźć: here

Drugim rozwiązaniem (które zastosowałem w naszej aplikacji) jest całkowite wyłączenie pulowania. Uwaga: rób to tylko wtedy, gdy aplikacja nie jest intensywna w DB (co było prawdą w naszym przypadku). Więc przełączyłem się na org.springframework.jdbc.datasource.DriverManagerDataSource. Konfiguracja, dla której wydaje się działać poprawnie, to:

<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" nie jest tak naprawdę pulą połączeń. http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/jdbc/datasource/DriverManagerDataSource.html – kosa

Powiązane problemy