Tomcat / H ibernate - Absturz nach Idle Zeit

Status
Nicht offen für weitere Antworten.

byte

Top Contributor
Guten Morgen,

ich habe einen Tomcat eingerichtet, auf dem meine Webanwendung läuft. Die Webanwendung verwendet Hibernate für die Zugriffe auf eine MySQL-Datenbank, die auf dem gleichen Server läuft wie der Tomcat. Die Webanwendung funktioniert prinzipiell einwandfrei, aber nach einer gewissen Zeit schmeisst der Tomcat folgende Exceptions:

Code:
org.hibernate.TransactionException: JDBC commit failed
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:130)
        at de.volkswagen.ap.website.filter.HibernateSessionFilter.commitTransactions(HibernateSessionFilter.java:32)
        at de.volkswagen.ap.website.filter.HibernateSessionFilter.doFilter(HibernateSessionFilter.java:76)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
        at java.lang.Thread.run(Thread.java:595)
Caused by: com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:888)
        at com.mysql.jdbc.Connection.getMutex(Connection.java:3728)
        at com.mysql.jdbc.Connection.commit(Connection.java:2267)
        at org.hibernate.transaction.JDBCTransaction.commitAndResetAutoCommit(JDBCTransaction.java:139)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:115)
        ... 15 more
org.hibernate.TransactionException: JDBC rollback failed
        at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:170)
        at de.volkswagen.ap.website.filter.HibernateSessionFilter.commitTransactions(HibernateSessionFilter.java:49)
        at de.volkswagen.ap.website.filter.HibernateSessionFilter.doFilter(HibernateSessionFilter.java:76)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
        at java.lang.Thread.run(Thread.java:595)
Caused by: com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:888)
        at com.mysql.jdbc.Connection.getMutex(Connection.java:3728)
        at com.mysql.jdbc.Connection.rollback(Connection.java:5204)
        at org.hibernate.transaction.JDBCTransaction.rollbackAndResetAutoCommit(JDBCTransaction.java:183)
        at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:162)
        ... 15 more

Zur Erklärung: HibernateSessionFilter ist ein ServletFilter, der gemäß "Open Session in View" zunächst die Hibernate Transaktion öffnet, dann das Servlet ausführt und am Ende die Transaktion commitet, wenn die JSP gerendert wurde. Die Exceptions fliegen beim commit()-Aufruf, aber halt erst nach einer bestimmten Idle-Zeit. Sprich: Die Webapp funktioniert den ganzen Werktag einwandfrei, erst am nächsten Morgen ist sie abgeschossen, so dass ich den Tomcat neu starten muss.

Leider sind meine Datenbankkenntnisse sehr beschränkt. Meine Vermutung ist, dass irgendwann die DB-Connections verfallen und deswegen keine Verbindung zur DB mehr besteht. Kann es daran liegen, dass ich Hibernate falsch konfiguriert habe? Die Context Session Strategie von Hibernate steht auf Thread. AutoReconnect ist auf true.

Vielleicht hat ja einer ne Idee!? Wäre klasse!

TIA byto


Edit:"Der Titel darf aus Spamschutzgründen nicht das Wort 'hi' enthalten !" ???:L
 

ms

Top Contributor
byto hat gesagt.:
Die Context Session Strategie von Hibernate steht auf Thread.
Was genau bedeutet das? Hast du vielleicht einen Link?
Für mich hört es sich an, als ob nie ein commit() ausgeführt wird und, so wie du sagst, die Datenbankverbindung irgendwann dahin ist.

Hast du den HibernateSessionFilter selbst implementiert (Code ?) oder den aus dem Springframework verwendet?

ms
 

byte

Top Contributor
Ich habe mich an der Hibernate Doku orientiert beim Session Filter:

http://www.hibernate.org/43.html

Mit Session Context Strategie meine ich folgende Konfiguration:

Code:
<property name="current_session_context_class">thread</property>

Das heisst, ich hole mir die Hib. Session über factory.getCurrentSession() und schließe sie nicht explizit. Vermute, dass da der Fehler liegen könnte. Spring verwende ich nicht.

Commits werden definitiv gemacht. Die Webapp läuft viele Stunden ohne Probleme und Daten werden auch korrekt in die DB geschrieben.

Meine Vermutung ist, dass irgendwann ein Timeout bei der MySQL DB ausläuft und die Connections weg sind, die Hibernate Sessions jedoch davon nichts mitkriegen!?
 

byte

Top Contributor
Habe das Problem gelöst. MySQL schließt die Connections per Default nach 8 Stunden Inaktivität. Ich habe den Fehler gemacht, Hibernate mit dem Standard Connection Pool zu konfigurieren. Benutze jetzt C3PO als Connection Pool und damit funktionierts jetzt.

Meine Konfiguration:

Code:
      <property name="c3p0.acquire_increment">1</property>
      <property name="c3p0.idle_test_period">100</property> 
      <property name="c3p0.max_size">100</property>
      <property name="c3p0.max_statements">0</property>
      <property name="c3p0.min_size">10</property>
      <property name="c3p0.timeout">100</property>

Dazu muss noch die C3PO Jar-Datei in den Classpath (liegt Hibernate bei).

Zum Testen kann man bei MySQL die Variable wait_timeout auf einen kleinen Wert stellen. Dann muss man nicht 8h warten. ;)
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben