2012-10-29 270 views
4

我們正在研究一個帶有Hibernate 3 ORM的java struts2框架web應用程序。我們使用mysql作爲我們的數據庫。休眠/ mysql連接問題

我們在日誌中發現了一些DB相關的異常。在配置的時間之前超時連接到數據庫。這裏是我們發現的共同特例。

104343235 [pool-6-thread-19] ERROR org.hibernate.util.JDBCExceptionReporter - The last packet successfully received from the server was 100,838,460 milliseconds ago. The last packet sent successfully to the server was 100,838,461 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. 

org.hibernate.exception.JDBCConnectionException: could not execute query 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:99) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
    at org.hibernate.loader.Loader.doList(Loader.java:2536) 
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276) 
    at org.hibernate.loader.Loader.list(Loader.java:2271) 
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452) 
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363) 
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196) 
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268) 
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102) 
    at com.myproject.model.dao.entities.EntitiesDAO.getByIds(EntitiesDAO.java:148) 

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 100,838,460 milliseconds ago. The last packet sent successfully to the server was 100,838,461 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. 
    at sun.reflect.GeneratedConstructorAccessor345.newInstance(Unknown Source)104343242 [pool-6-thread-16] ERROR org.hibernate.util.JDBCExceptionReporter - The last packet successfully received from the server was 100,838,544 milliseconds ago. The last packet sent successfully to the server was 100,838,544 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. 
104343242 [pool-6-thread-16] ERROR org.hibernate.util.JDBCExceptionReporter - The last packet successfully received from the server was 100,838,544 milliseconds ago. The last packet sent successfully to the server was 100,838,544 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. 

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525) 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) 
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1117) 
    at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3829) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2449) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2629) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2719) 
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155) 
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2318) 
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76) 
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208) 
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1953) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:802) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274) 
    at org.hibernate.loader.Loader.doList(Loader.java:2533) 
    ... 21 more 

我們每天都重新啓動我們的應用服務器,作爲該問題的臨時解決方案。

任何幫助將不勝感激。

+0

[參見此處以供參考](http://www.codefin.net/2007/05/hibernate-and-mysql-connection-timeouts.html) – gks

+0

我面臨同樣的問題。你如何解決這個問題? –

回答

5

發生這種情況是因爲MySQL服務器在超時後終止沒有活動的連接。 你需要幾行添加到DBCP配置 嘗試添加下列參數:

validationQuery="SELECT 1" 
testOnBorrow="true 

工作原理:連接池試圖返回連接之前運行validationQuery。如果validationQuesry失敗,dbcp將放棄連接,創建一個新連接並將其返回。

下面是一個例子:

<Resource name="jdbc/cooldatabase" 
      description="Strandls.com license database" 
      auth="Container" 
      type="javax.sql.DataSource" 
      factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" 
      driverClassName="com.mysql.jdbc.Driver" 
      url="jdbc:mysql://localhost:3306/cooldatabase?autoReconnect=true" 
      username="cooluser" 
      password="coolpassword" 
      initialSize="0" 
      maxActive="20" 
      maxIdle="10" 
      minIdle="0" 
      maxWait="-1" 
      validationQuery="SELECT 1" 
      testOnBorrow="true" 
      poolPreparedStatements="true" 
      removeAbandoned="true" 
      removeAbandonedTimeout="60" 
      logAbandoned="true"/> 

您可以在這裏找到完整的詳細信息:http://amitcodes.wordpress.com/2008/07/26/16/

+0

如何爲c3p0連接池實現相同? –

+0

我從來沒有與C3P0工作,到目前爲止,但按照討論中,有一個叫testConnectionOnCheckout屬性: '<屬性名= 「testConnectionOnCheckout」>真' [這裏](HTTPS://forum.hibernate .org/viewtopic.php?f = 1&t = 1015229)是完整的討論:https://forum.hibernate.org/viewtopic.php?f=1&t=1015229 –

+0

來源:https://community.jboss.org/ wiki/HowToConfigureTheC3P0ConnectionPool?_sscc = t 'testConnectionOnCheckout'必須在'c3p0.properties'中設置,默認值爲false。 不要使用它,這個功能非常昂貴。如果設置爲true,則將在每個連接檢出時執行操作以驗證連接是否有效。更好的選擇是使用'c3p0.idleConnectionTestPeriod'定期驗證連接。 –