2012-03-14 15 views
2

私たちのサーバーでmysql接続に問題があります。 WebAppは正常に動作しますが、数時間後にmysqlとの接続からエラーが発生します。 休止状態のセッションに何か問題があると考えています。私たちが知る限り、ハイバネートが同じセッションを使用しようとする間、mysql接続は閉じられます。 おそらく、セッションを正しく終了していない可能性があります。Hibernate connection timeout

私たちはStruts 2を使用しており、すべてのセッション処理を管理するインターセプタを定義しました。 は、ここでは、コードです:あなたが見ることができるように、我々はcurrentSessionを取得しようとしている

public class OSVStrutsInterceptors implements Interceptor { 

private static SessionFactory sf; 

@Override 
public void destroy() { 

    try 
    { 
     sf.getCurrentSession().close(); 
    } 
    catch (HibernateException ex) 
    { 
     throw new RuntimeException(ex); 
    } 
} 

@Override 
public void init() { 

} 

@Override 
public String intercept(ActionInvocation ai) throws Exception { 
    sf = HibernateUtil.getSessionFactory(); 
    Session sesion=sf.getCurrentSession(); 
    try { 
    sesion.beginTransaction(); 
    } 
    catch (Exception ex) { 
     System.out.println(new Date()+" Sesion cerrada. Obtenemos una nueva"); 
     sesion=sf.openSession(); 
    } 

    String result=ai.invoke(); 
    sesion.getTransaction().commit(); 

    return result; 

} 
} 

が、できない場合、我々は新しいセッションを開きます。また、インターセプタのdestroy()メソッドでセッションを閉じます。

しかし、私たちは常にサーバー上でこのエラーを取得:

com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.net.SocketException 
MESSAGE: Broken pipe 

STACKTRACE: 

java.net.SocketException: Broken pipe 

答えて

4

autoReconnect=trueの追加のMySQL(参照を見つけることができませんでした)によって推奨されません。代わりにhibernate.cfg.xml

<!-- c3p0 --> 
<property name="hibernate.c3p0.validate">true</property> 
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property> 
<property name="hibernate.c3p0.min_size">5</property> 
<property name="hibernate.c3p0.max_size">600</property> 
<property name="hibernate.c3p0.timeout">1800</property> 
<property name="hibernate.c3p0.max_statements">50</property> 
<property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property> 
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property> 
<property name="hibernate.c3p0.idle_test_period">3000</property> 

にこれらの行を追加し、私はorg.apache.commons.dbcp.BasicDataSourceを使用するカスタムされたConnectionProviderを使用し、あなたのCLASSPATH

hibernate-c3p0-4.0.0.Final.jar 
c3p0-0.9.1.jar (Not sure if this is neccessary) 
1

通信リンクの障害は、ネットワーク障害、ルータの設定ミス、または他のネットワークの問題など、任意の数の理由のために起こることができます。あなたの接続が単にタイムアウトしている可能性もありますが、可能性はあります。いずれにしても、自動的に再接続するようにMySQLデータソースを設定することで、問題を解決できます。これを行う1つの方法は、JDBCのURLに適切なプロパティを指定することにより、次のとおりです。

url="jdbc:mysql://localhost:3306/mydb?autoReconnect=true 
0

にこれらのライブラリを追加します。

 setValidationQuery("select 1"); 
     setTestOnBorrow(true); 

注:このクラスでは、あなたが設定する必要があり、私はnet.sf.log4jdbc.ConnectionSpyとの接続を包むが、あなたは行うことができない、それhibernate.cfgで

<property name="hibernate.connection.provider_class"> 
    example.DBCPConnectionProvider 
</property> 





public class DBCPConnectionProvider implements ConnectionProvider { 
    private static final long serialVersionUID = -4063997930726759172L; 

    private static final Logger log = Logger.getLogger(DBCPConnectionProvider.class); 

    static CustomDataSource ds; 

    static{ 
     try { 
      ds = new CustomDataSource();  
     } catch (Exception e) { 
      log.error("", e); 
     } 
    } 


    @Override 
    public void closeConnection(Connection conn) throws SQLException { 
     conn.close(); 
    } 

    @Override 
    public Connection getConnection() throws SQLException { 
     return ds.getConnection(); 
    } 




    @Override 
    public boolean supportsAggressiveRelease() { 
     return true; 
    } 

    @Override 
    public boolean isUnwrappableAs(Class arg0) { 
     return false; 
    } 

    @Override 
    public <T> T unwrap(Class<T> arg0) { 
     return null; 
    } 

    } 









public class CustomDataSource extends BasicDataSource{ 
    private static final Logger log = Logger.getLogger(CustomDataSource.class); 


    public CustomDataSource(){ 
     Properties props = HibernateConfiguration.getProperties(); 
      setDriverClassName(props.getProperty("hibernate.connection.driver_class") ); 
      setUsername( props.getProperty("hibernate.connection.username")); 
      setPassword(props.getProperty("hibernate.connection.password") ); 
      setUrl(props.getProperty("hibernate.connection.url") ); 
      setValidationQuery("select 1"); 
      setTestOnBorrow(true); 

    } 

    @Override 
    public Connection getConnection() throws SQLException{ 

     return new net.sf.log4jdbc.ConnectionSpy(super.getConnection()); 
    } 
}