org.hibernate.exception.JDBCConnectionException: could not execute query
at 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.CommunicationsException
MESSAGE: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.net.SocketException
MESSAGE: Broken pipe
STACKTRACE:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
......
** END NESTED EXCEPTION **
|
查看了Mysql的文檔,以及Connector/J的文檔以及在線說明發現,出現這種異常的緣由是:html
Mysql服務器默認的「wait_timeout」是8小時,也就是說一個connection空閒超過8個小時,Mysql將自動斷開該connection。這就是問題的所在,在C3P0 pools中的connections若是空閒超過8小時,Mysql將其斷開,而C3P0並不知道該connection已經失效,若是這時有Client請求connection,C3P0將該失效的Connection提供給Client,將會形成上面的異常。java
解決的方法有3種:mysql
固然最好的辦法是同時綜合使用上述3種方法,下面就 DBCP、C3P0 和 simple jdbc dataSource 分別作一說明,假設 wait_timeout 爲默認的8小時web
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"
//獲取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
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]後面添加上:sql
wait_timeout = n
interactive-timeout = n
|
其中 n 爲服務器關閉交互式鏈接前等待活動的秒數。但是就部署而言每次修改 my.ini 比較麻煩,並且 n 等於多少纔是合適的值呢? 因此並不推薦這個解決辦法。)數據庫
原文地址:http://www.cnblogs.com/hemingwang0902/archive/2012/03/15/2397620.html服務器
附件:網絡
? BasicDataSource 相關的參數說明app
? 在使用DBCP的時候,若是使用默認值,則數據庫鏈接由於某種緣由斷掉後,再從鏈接池中取得鏈接又不進行驗證,這時取得的鏈接實際上就會是無效的數據庫鏈接。所以爲了防止得到的數據庫鏈接失效,在使用的時候最好保證:less
? PS:在構造GenericObjectPool [BasicDataSource在其createDataSource () 方法中也會使用GenericObjectPool] 時,會生成一個內嵌類Evictor,實現自Runnable接口。若是timeBetweenEvictionRunsMillis大於0,每過timeBetweenEvictionRunsMillis毫秒Evictor會調用evict()方法,檢查對象的閒置時間是否大於 minEvictableIdleTimeMillis毫秒(_minEvictableIdleTimeMillis小於等於0時則忽略,默認爲30分鐘),是則銷燬此對象,不然就激活並校驗對象,而後調用ensureMinIdle方法檢查確保池中對象個數不小於_minIdle。在調用returnObject方法把對象放回對象池,首先檢查該對象是否有效,而後調用PoolableObjectFactory 的passivateObject方法使對象處於非活動狀態。再檢查對象池中對象個數是否小於maxIdle,是則能夠把此對象放回對象池,不然銷燬此對象
? 上述特性的可設置性已在代碼中驗證,具體性能是否能實現有待實際驗證
? C3P0的官方example中使用的數據源爲ComboPooledDataSource,網上一篇文章詳細介紹了C3P0鏈接池配置中各項含義[這些配置項的含義在下載解壓c3p0的壓縮包以後目錄的doc\index.html中的Configuration部分也有詳細的介紹,這裏偷下懶:P],現摘錄以下:
3
30
1000
false
Test
">false
100
e">
null
nsactions">false
">60
3
60
15
100
on">
3
root
password
select id from test where id=1
300
">false
true
root
eProxies">false
con_test
30000
">30
10
30
25
10
0
200
300
? 上述特性的可設置性已在代碼中驗證,具體性能是否能實現有待實際驗證
? 從配置項的內容來看,C3P0和DBCP都有比較詳細的有關鏈接檢測保證的配置,咱們能夠看到C3P0能夠控制數據源內加載的PreparedStatements數量,而且能夠設置幫助線程的數量來提高JDBC操做的速度,這些是DBCP未提供的;另外從網絡上的評價來看,DBCP出現Bug的頻率要大於C3P0,不過這一點有待於咱們本身實際的檢測。
? Proxool的使用和dbcp以及c3p0稍有不一樣,咱們須要而且只須要在使用基本的java.sql.DriverManager以前加載org.logicalcobwebs.proxool.ProxoolDriver驅動類,而且按照proxool定義的url格式 ["proxool." + alias + ":" + driverClass + ":" + driverUrl ,其中alias是爲鏈接池自定義的別名] 來得到connection;具體的能夠參看proxool doc下的UserGuide,或本文所附的示例代碼。下面對鏈接池的特性配置做詳細說明 [這個是本身翻譯的,不必定準確,有問題時請參看doc下的Properties ~]。
n fatal-sql-exception
以逗號隔開的異常列表,當設置了此項以後,每當出現SQLException時都將與列表中異常項做比較,若是匹配則認爲出現fatal異常,這將致使connection被丟棄,而且不論出現任何狀況該異常將被重拋一次以通知用戶發生的狀況。默認值爲null
n fatal-sql-exception-wrapper-class
若是配置了fatal-sql-exception,則默認的操做是丟 棄引發SQLException的緣由而只是拋出原始異常。使用fatal-sql-exception-wrapper-class這個特性能夠將 SQLException包裝到繼承SQLException或RunTimeException的任何異常類裏。Proxool提供了兩個類供使用 FatalSQLException和FatalRunTimeException;使用這兩個類的話就將該選項設置爲 'org.logicalcobwebs.proxool.FatalSQLException'或者 'org.logicalcobwebs.proxool.FatalRuntimeException'。默認值爲null
n house-keeping-sleep-time
proxool自動偵察各個鏈接狀態的時間間隔(毫秒),偵察到空閒的鏈接就立刻回收,超時的銷燬,默認值爲30秒
n house-keeping-test-sql
若是偵察線程發現閒置鏈接,則會使用這個SQL語句來對這些鏈接進行檢查;這項設置的語句應該可以被很快的執行,例如查詢當前時間 [info.setProperty("proxool.house-keeping-test-sql", "select CURRENT_DATE");] 。若是不設置則該選項被忽略
n injectable-connection-interface、injectable-statement-interface、injectable-prepared-statement-interface、injectable-callable-statement-interface
n jmx
若是此項設爲true,則鏈接池將被以名稱"Proxool:type=Pool, name="註冊爲JMS Server的MBean。默認值爲false
n jmx-agent-id
當且僅當jmx選項設爲true時使用,爲以逗號分隔的鏈接持註冊到的JMS代理名稱列表;若是不設置則全部註冊的JMX Server都將被使用
n maximum-active-time
線程最大存活時間,超過此時間的線程將被守護線程kill掉,默認值爲5分鐘
n maximum-connection-count
到數據庫的最大鏈接數,超過了這個鏈接,再有請求時,就排在隊列中等候,最大的等待請求數由simultaneous-build-throttle決定;默認值爲15
n maximum-connection-lifetime
鏈接最大存活時間,毫秒爲單位,默認值爲4小時
n minimum-connection-count
不論是否被使用都保持開放的最小鏈接數,默認值爲5
n overload-without-refusal-lifetime
用來判斷鏈接池狀態,若是在此選項設置時間內(毫秒爲單位)拒絕了鏈接,則認爲過負載。默認值爲60秒
n prototype-count
最少保持的空閒鏈接數,注意與minimum-connection-count區分。默認值爲0
n simultaneous-build-throttle
最大的等待請求數,默認值爲10
n test-before-use
若是設爲true則connection在使用前將以house-keeping-test-sql設置的語句測試,若是測試不經過則該connection被丟棄並會從新分配一個connection。默認爲false
n test-after-use
若是設爲true則connection在關閉(放回鏈接池)前將以house-keeping-test-sql設置的語句測試,若是測試不經過connection將被丟棄。默認值爲false
? 與其它鏈接池特性的設置方法不一樣,Proxool不提供相應的set方法,全部特性都要以諸如info.setProperty("proxool.jmx", "false");方式設定
? 上述特性的可設置性已在代碼中驗證,具體性能是否能實現有待實際驗證
原文地址:http://zhangsha1251.blog.163.com/blog/static/62624053201182111921783/