myBatis串連MySQL報異常:No operations allowed after connection closed.Connection was implicitly closed

來源:互聯網
上載者:User
異常資訊
org.hibernate.exception.JDBCConnectionException: could not execute queryat org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:74)at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43).......Caused by: com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: No operations allowed after connection closed.Connection was implicitly closed due to underlying exception/error:** BEGIN NESTED EXCEPTION **com.mysql.jdbc.CommunicationsExceptionMESSAGE: Communications link failure due to underlying exception:** BEGIN NESTED EXCEPTION **java.net.SocketExceptionMESSAGE: Broken pipeSTACKTRACE:java.net.SocketException: Broken pipeat java.net.SocketOutputStream.socketWrite0(Native Method)......** END NESTED EXCEPTION **
原因分析

查看了Mysql的文檔,以及Connector/J的文檔以及線上說明發現,出現這種異常的原因是:

  Mysql伺服器預設的“wait_timeout”是8小時,也就是說一個connection空閑超過8個小時,Mysql將自動斷開該connection。這就是問題的所在,在C3P0 pools中的connections如果空閑超過8小時,Mysql將其斷開,而C3P0並不知道該connection已經失效,如果這時有Client請求connection,C3P0將該失效的Connection提供給Client,將會造成上面的異常。

解決方案

解決的方法有3種:

  1. 增加 wait_timeout 的時間。
  2. 減少 Connection pools 中 connection 的 lifetime。
  3. 測試 Connection pools 中 connection 的有效性。

當然最好的辦法是同時綜合使用上述3種方法,下面就 DBCP、C3P0 和 simple jdbc dataSource 分別做一說明,假設 wait_timeout 為預設的8小時

DBCP 增加以下配置資訊:
validationQuery = "select 1"

testWhileIdle = "true"

//some positive integer
timeBetweenEvictionRunsMillis = 3600000

//set to something smaller than 'wait_timeout'
minEvictableIdleTimeMillis = 18000000

//if you don't mind a hit for every getConnection(), set to "true"
testOnBorrow = "true"
C3P0 增加以下配置資訊:
//擷取connnection時測試是否有效
testConnectionOnCheckin = true

//自動化的測試的table名稱
automaticTestTable=C3P0TestTable

//set to something much less than wait_timeout, prevents connections from going stale
idleConnectionTestPeriod = 18000

//set to something slightly less than wait_timeout, preventing 'stale' connections from being handed out
maxIdleTime = 25000

//if you can take the performance 'hit', set to "true"
testConnectionOnCheckout = true
simple jdbc dataSource 增加以下配置資訊:
Pool.PingQuery = select 1

Pool.PingEnabled = true

Pool.PingConnectionsOlderThan = 0

//對於閒置串連一個小時檢查一次
Pool.PingConnectionsNotUsedFor = 3600000
其他方案(不推薦)

  對於 MySQL5 之前的版本,如 Mysql4.x,只需要修改串連池配置中的 URL,添加一個參數:autoReconnect=true(如jdbc:mysql://hostaddress:3306/schemaname?autoReconnect=true),如果是 MySQL5 及以後的版本,則需要修改 my.cnf(或者my.ini) 檔案,在 [mysqld] 後面添加上:

wait_timeout = ninteractive-timeout = n

其中 n 為伺服器關閉互動式串連前等待活動的秒數。可是就部署而言每次修改 my.ini 比較麻煩,而且 n 等於多少才是合適的值呢? 所以並不推薦這個解決辦法。)

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.