使用Hibernate + MySQL數據庫開發,連接超時問題:java
com.mysql.jdbc.CommunicationsException: The last packet successfully received from the server was58129 seconds ago.The last packet sent successfully to the server was 58129 seconds ago, which 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.mysql
查了一下,原來是mysql超時設置的問題
若是鏈接閒置8小時 (8小時內沒有進行數據庫操做), mysql就會自動斷開鏈接, 要重啓tomcat.linux
解決辦法:sql
一種. 若是不用hibernate的話, 則在 connection url中加參數: autoReconnect=true數據庫
jdbc.url=jdbc:mysql://ipaddress:3306/database?autoReconnect=true&autoReconnectForPools=true
二種。用hibernate的話, 加以下屬性:
<property name=」connection.autoReconnect」>true</property>
<property name=」connection.autoReconnectForPools」>true</property>
<property name=」connection.is-connection-validation-required」>true</property>
三。要是還用c3p0鏈接池:
<property name=」hibernate.c3p0.acquire_increment」>1</property>
<property name=」hibernate.c3p0.idle_test_period」>0</property>
<property name=」hibernate.c3p0.timeout」>0</property>
<property name=」hibernate.c3p0.validate」>true</property>windows
四。最很差的解決方案tomcat
使用Connector/J鏈接MySQL數據庫,程序運行較長時間後就會報如下錯誤:服務器
Communications link failure,The last packet successfully received from the server was *** millisecond ago.The last packet successfully sent to the server was *** millisecond ago。網絡
其中錯誤還會提示你修改wait_timeout或是使用Connector/J的autoReconnect屬性避免該錯誤。app
後來查了一些資料,才發現遇到這個問題的人還真很多,大部分都是使用鏈接池方式時纔會出現這個問題,短鏈接應該很難出現這個問題。這個問題的緣由:
MySQL服務器默認的「wait_timeout」是28800秒即8小時,意味着若是一個鏈接的空閒時間超過8個小時,MySQL將自動斷開該鏈接,而鏈接池卻認爲該鏈接仍是有效的(由於並未校驗鏈接的有效性),當應用申請使用該鏈接時,就會致使上面的報錯。
1. 按照錯誤的提示,能夠在JDBC URL中使用autoReconnect屬性,實際測試時使用了autoReconnect=true& failOverReadOnly=false,不過並未起做用,使用的是5.1版本,可能真像網上所說的只對4以前的版本有效。
2.沒辦法,只能修改MySQL的參數了,wait_timeout最大爲31536000即1年,在my.cnf中加入:
[mysqld]
wait_timeout=31536000
interactive_timeout=31536000
重啓生效,須要同時修改這兩個參數。
** BEGIN NESTED EXCEPTION **
com.mysql.jdbc.CommunicationsException
MESSAGE: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
Java.io.EOFException
STACKTRACE:
java.io.EOFException
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2304)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2803)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3176)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1153)
interactive_timeout=28800000
wait_timeout=28800000
「com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure-
Last packet sent to the server was 0 ms ago.
通過一番調研,發現不少人都碰到過相似問題,但網上使人滿意的回答並很少。mysql網站上的提問也不少,但並無正確答案;百度知道上卻是有一個近似正確的回答。現將本人的解決辦法總結一下
上述問題是由mysql5數據庫的配置引發的。mysql5將其鏈接的等待時間(wait_timeout)缺省爲8小時。在其客戶程序中能夠這樣來查看其值:
mysql﹥
mysql﹥ show global variables like ‘wait_timeout’;
+—————+———+
| Variable_name | Value |
+—————+———+
| wait_timeout | 28800 |
1 row in set (0.00 sec)
28800 seconds,也就是8小時。
若是在wait_timeout秒期間內,數據庫鏈接(java.sql.Connection)一直處於等待狀態,mysql5就將該鏈接關閉。這 時,你的Java應用的鏈接池仍然合法地持有該鏈接的引用。當用該鏈接來進行數據庫操做時,就碰到上述錯誤。這解釋了爲何個人程序次日不能登陸的問 題。
你可能會想到在tomcat的數據源配置中有沒有辦法解決?的確,在jdbc鏈接url的配置中,你能夠附上「autoReconnect=true」,但這僅對mysql5之前的版本起做用。增長「validation query」彷佛也無濟於事。
本人以爲最簡單的辦法,就是對症下藥:既然問題是由mysql5的全局變量wait_timeout的缺省值過小引發的,咱們將其改大就行了。
查 看mysql5的手冊,發現對wait_timeout的最大值分別是24天/365天(windows/linux)。以windows爲 例,假設咱們要將其設爲21天,咱們只要修改mysql5的配置文件「my.ini」(mysql5 installation dir),增長一行:wait_timeout=18144006
須要從新啓動mysql5。
linux系統配置文件:/etc/my.cnf
測試顯示問題解決了。
-------------------------------------------
[mysqld]
wait_timeout=2147483 interactive_timeout=2147483