2009-04-06 3 views
3

Ich habe eine Java-Webapp mit Hibernate und MySQL. Wenn die Site nicht für ein paar Tage verwendet wird, geht die MySQL-Verbindung abgestanden, und ich bin mit der folgenden Ausnahme erfüllt:Wie veraltete MySQL/Hibernate-Verbindungen zu vermeiden sind (MySQLNonTransientConnectionException)

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state. 

Aus Erfahrung roh JDBC es möglich ist, die Verbindung zu konfigurieren, zu versuchen, sich zu erholen von Fehlern oder veralteten Verbindungen, aber ich weiß nicht, wie man das mit Hibernate macht. Ich nenne nicht explizit close() irgendwo (aber ich wette Hibernate tut irgendwo tief in seinen Eingeweiden).

Weiß jemand, was ich tun soll?

+0

Haben Sie versucht, "isValid" für die Verbindung zu verwenden, um zu testen, ob die Verbindung gültig ist, und wenn nicht, dann stellen Sie die Verbindung wieder her. Ich denke, das sollte das Problem lösen, ohne die Servereinstellungen ändern zu müssen – Jus12

Antwort

3

Ich hatte dieses Problem. Die Verwendung von Verbindungs-Pooling (c3p0) machte es weg. Im Allgemeinen ist es auch eine gute Idee, ein Verbindungspooling zu verwenden.

2

Danke für den Rat. Für die Nachwelt willen, änderte ich den hibernate.cfg.xml der folgenden Optionen:

<property name="connection.url">jdbc:mysql://localhost/FooDB</property> 
<property name="connection.username">root</property> 
<property name="connection.driver_class">com.mysql.jdbc.Driver</property> 
<property name="dialect">org.hibernate.dialect.MySQLDialect</property> 
<property name="connection.password">secret</property> 
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property> 

... auf die folgenden:

<property name="connection.datasource">java:/comp/env/jdbc/FooDB</property> 
<property name="dialect">org.hibernate.dialect.MySQLDialect</property> 

Dies auch das Hinzufügen erforderlich, um eine Standard 'Kontext' Eintrag in meiner Web App context.xml:

<Resource name="jdbc/FooDB" 
      auth="Container" 
      type="javax.sql.DataSource" 
      maxActive="100" 
      maxIdle="30" 
      maxWait="10000" 
      username="root" 
      password="secret" 
      driverClassName="com.mysql.jdbc.Driver" 
      url="jdbc:mysql://localhost:3306/ss?autoReconnect=true" /> 

1

Wir hatten ein ähnliches Problem der Hibernate-Mysql-Verbindung, die Zeitlimit überschritten. So haben wir versucht, C3P0 mit folgenden Konfiguration:

<property name=c3p0.acquire_increment>1</property> 
<property name=c3p0.idle_test_period>3600</property> 
<property name=c3p0.max_statements>0</property> 
<property name=c3p0.min_size>1</property> 
<property name=c3p0.timeout>3605</property> 
<property name=hibernate.c3p0.preferredTestQuery>select 1;</property> 

Hibernate connection_pool Größe 1.em

gesetzt wurde gemacht das Timeout Problem weggehen. Aber wir haben uns einem anderen Problem gestellt. Lange Wartezeiten. Wir haben einen Dienst (Servlet läuft auf jboss), der etwa 5-6 Anfragen pro Sekunde empfängt. Jede Anfrage muss sich über Hibernate mit mysql verbinden. Die meisten unserer Anfragen selektieren mit einer Insert/Update jede fünfte bis sechste Anfrage. Normalerweise die anfrage serve zeit für uns ist 2-3ms für wählen und 40-50ms für einfügen/update. Aber nachdem wir die obige C3P0-Konfiguration verwendet hatten, sahen wir, dass jede Anfrage, die nach einem Update abgeschlossen wurde, fast 4-5 Minuten dauerte! Aus unseren Protokollen scheint es, dass eine ausgewählte Anfrage nach dem Zufallsprinzip hängen bleibt und erst abgeschlossen werden kann, nachdem eine Aktualisierungsanforderung empfangen und geliefert wurde.

Das obige Problem verschwindet, wenn wir die C3P0-Konfiguration entfernen. Kann jemand vorschlagen, was wir falsch machen könnten?

Dies ist die komplette Hibernate Config-Referenz:

<?xml version="1.0" encoding="utf-8" ?> 
<!DOCTYPE hibernate-configuration PUBLIC 
      "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
      "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
    <session-factory> 
     <property name="connection.driver_class">com.mysql.jdbc.Driver</property> 
     <property name="connection.url">jdbc:mysql://xxx.xxx.xxx</property> 
     <property name="connection.username">xxx</property> 
     <property name="connection.password">xxx</property> 
     <property name="connection.pool_size">1</property> 
     <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 
     <property name="current_session_context_class">thread</property> 
     <property name="hibernate.cache.use_query_cache">false</property> 
     <property name="hibernate.cache.use_second_level_cache">false</property> 
     <property name="show_sql">true</property> 
     <!-- Transaction isolation 2 = READ_COMMITTED --> 
     <property name="connection.isolation">2</property> 
     <property name="connection.autocommit">true</property> 
     <!-- configuration pool via c3p0--> 
     <property name="c3p0.acquire_increment">1</property> 
     <property name="c3p0.idle_test_period">3600</property> <!-- seconds --> 
     <property name="c3p0.max_size">1</property> 
     <property name="c3p0.max_statements">0</property> 
     <property name="c3p0.min_size">1</property> 
     <property name="c3p0.timeout">3605</property> <!-- seconds --> 
     <property name="hibernate.c3p0.preferredTestQuery">select 1;</property> 
    </session-factory> 
</hibernate-configuration> 
1
<property name="c3p0.acquire_increment">1</property> 
<property name="c3p0.idle_test_period">120</property> <!-- seconds --> 
<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">180</property> <!-- seconds --> 

überschreiben diese Einstellungen auf die Config-Datei. Es hilft dir.

Verwandte Themen