2009-04-06 7 views
3

私は、HibernateとMySQLを使用しているJava Webアプリケーションを持っています。サイトは数日のために使用されていない場合は、MySQLの接続が古くなって、私は次の例外と会っています:MySQL/Hibernate接続が古くなるのを避ける方法(MySQLNonTransientConnectionException)

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

経験から生のJDBCを使用して、それを回復しようとする接続を設​​定することが可能ですエラーや古い接続からのものですが、Hibernateを使用してこれを行う方法はわかりません。私は明示的にclose()をどこにでも呼び出すわけではありません(しかし、私はHibernateがどこかで深いところまで下がっていると賭けています)。

私は何をすべきか知っていますか?

+0

接続が有効かどうかをテストする接続に 'isValid'を使ってみましたか?そうでない場合は再接続しましたか?サーバーの設定を変更しなくても問題を解決できるはずだと思います – Jus12

答えて

4

どの接続プールを使用していますか?

Hibernate suggestionは、組み込みプーリングを使用するのではなく、Commons DBCPまたはC3POなどのアプリケーションサーバーデータソースを使用します。

3

私はその問題を抱えていました。接続プール(c3p0)を使用すると、それがなくなりました。一般的には、接続プーリングを使用することもお勧めします。

2

アドバイスをいただきありがとうございます。後世のために、私は次からはhibernate.cfg.xmlを変更:

<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> 

...次へ:

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

これがまた私のウェブにおける標準「コンテキスト」エントリを追加する必要アプリのの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

私たちは、Hibernateのmysql接続がタイムアウトしたのと同じ問題を抱えていました。 は、だから我々は、以下の構成で、C3P0を試してみました:

<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サイズは、これは、タイムアウトの問題が離れて行かせた1

に設定しました。しかし、私たちは別の問題に直面しました。長い間待ちます。 私たちはサービス(サーブレットはjboss上で動作しています)を持っています。これは、毎秒5-6要求のようなものを受け取ります。すべてのリクエストは、hibernateを通じてmysqlに接続する必要があります。私たちのリクエストのほとんどは、5番目〜6番目のリクエストごとに挿入/更新されます。通常、リクエストの配信時間は、選択の場合は2〜3ms、挿入/更新の場合は40〜50msです。しかし、上記のC3P0設定を使用した後、更新後に完了するすべてのリクエストがほぼ4-5分かかることがわかりました。私たちのログからは、ランダムに選択要求が停止し、更新要求が受信されて配信された後にしか完了できないように見えました。

C3P0設定を削除すると上記の問題は解決します。誰かが間違ってやっていることを示唆することはできますか?

<?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 --> 

オーバーライドconfigファイルで次の設定を行います。

はここで参照するための完全な休止状態の設定です。それはあなたに役立ちます。