2012-01-30 471 views
5

我越來越可怕的MySQL JDBC陳舊連接異常:失效連接,validationQuery不能解決

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed. 
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 243,263,541 milliseconds ago. The last packet sent successfully to the server was 243,263,541 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. 

好像所有人都認爲這是通過使用validationQuery + testOnBorrow固定的,但是這並不是解決問題。

我使用以下軟件 的MySQL 5.1.41-3ubuntu12.10 連接器/ J 5.1.18 的Tomcat 6.0.24

這裏是如何連接在server.xml中定義,我們使用tomcat-dbcp來連接連接。

<Resource 
     auth="Container" 
     driverClassName="com.mysql.jdbc.Driver" 
     factory="org.apache.commons.dbcp.BasicDataSourceFactory" 
     logAbandoned="true" 
     maxActive="75" 
     maxIdle="20" 
     maxWait="10000" 
     name="jdbc/jndiname" 
     password="password" 
     removeAbandoned="true" 
     removeAbandonedTimeout="60" 
     validationQuery="/* ping */SELECT 1" 
     testOnBorrow="true" 
     testOnReturn="true" 
     timeBetweenEvictionRunsMillis="10000" 
     testWhileIdle="true" 
     scope="Shareable" 
     type="javax.sql.DataSource" 
     url="jdbc:mysql://host:3306/schema" 
     username="username" /> 
+0

在什麼情況下你會得到那些陳舊的連接異常?你是否發送了一個實時查詢,這就是結果?你是否像查詢那樣創建了JDBC連接,還是從連接池中抓取它們? – technocrat 2012-01-30 19:59:27

+0

每天早上當用戶首次連接到我們的Web應用程序時,會發生連接異常。連接來自Tomcat-DBCP池。我們可以通過每天重新啓動Tomcat來解決問題,但這隻能掩蓋真正的問題。 – user763648 2012-01-30 20:06:19

+0

重新啓動Tomcat時,所做的只是使連接池自行備份。你相信這個修復會被tomcat配置,mysql配置或tomcat-dbcp池代碼改變嗎?只是讓我知道尋找答案的方向。 – technocrat 2012-01-30 22:47:08

回答

0

我可能會檢查my.cnf文件中的wait_timeout。默認值是28800秒或8小時。它的最大時間爲31536000秒或365天。

對於您注意到的第一個異常:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException,我過去將它封裝在try/catch塊中。在catch中,對於那個異常,我有連接重新連接,然後重新發送查詢。爲了知道我不想經常這樣做,並且仍然保持開放連接,我還將默認的wait_timeout增加到了我的應用程序的合理值。

參見本手冊參考:http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_wait_timeout

+1

我們的wait_timeout設置爲默認的28800秒,但我們寧願修復問題的根本原因,而不僅僅是減少頻率。 – user763648 2012-01-30 20:08:19

+0

它至少會給你一些喘息的空間,直到你能修好它。這個價值是說如下:如果我的連接未使用28800秒,終止它!在你的系統上,如果你的Tomcat-DBCP池不能保持它的連接處於活動狀態(如DDL或DML語句/ query/insert/select ..),那麼MySQL將在8小時後終止連接,儘管你可能還沒有意識到直到你嘗試執行所說的DDL/DML。你可以在你設置連接池的地方發佈代碼嗎? MySQL中的類似問題:http://forums.mysql.com/read.php?39,501441,501692#msg-501692 – technocrat 2012-01-30 22:44:04

+0

我已經更新了這個問題,以包含server.xml中的完整連接屬性。我們所有的數據庫邏輯都是從Hibernate層開始的,通過tomcat-dbcp到Connector/J驅動程序。 – user763648 2012-01-30 23:02:17

0

您的驗證查詢是不正確。刪除「選擇1」並僅保留ping。

+0

不正確,請參閱http://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-j2ee-concepts-connection-pooling.html 要使用此功能,請在您的連接池以/ * ping開頭*/ 'protected static final String PING_MARKER =「/ * ping * /」;' '...' 'if(sql.charAt(0)=='/' ){' 'if(sql.startsWith(PING_MARKER)){' 'doPingInstead();' '}' – user763648 2015-09-16 02:59:14

+0

我根據我的迴應:https://dev.mysql.com/doc/connector-j /en/connector-j-usagenotes-tomcat.html 以下XML代碼段說明如何選擇此選項: validationQuery /* *平/ 注意/ * *平/必須嚴格說明。 – Mike 2015-10-13 16:25:06

0

在你mysqlmy.cnf,設置以下屬性來個大值樣365天 -

wait_timeout = 31536000
interactive_timeout = 31536000

會議wait_timeout值將與非交互式連接全球wait_timeout值初始化以及交互式連接的全局值interactive_timeout

PS - 兩個值均以秒爲單位。

相關問題