MyBatis連接MySQL出錯:No operations allowed after connection closed

異常信息
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的文檔以及在線說明發(fā)現(xiàn)抵乓,出現(xiàn)這種異常的原因是:
  Mysql服務(wù)器默認(rèn)的“wait_timeout”是8小時摆寄,也就是說一個connection空閑超過8個小時颂碘,Mysql將自動斷開該connection。這就是問題的所在返敬,在C3P0 pools中的connections如果空閑超過8小時遂庄,Mysql將其斷開,而C3P0并不知道該connection已經(jīng)失效救赐,如果這時有Client請求connection涧团,C3P0將該失效的Connection提供給Client只磷,將會造成上面的異常经磅。
解決方案
解決的方法有3種:
增加 wait_timeout 的時間泌绣。
減少 Connection pools 中 connection 的 lifetime。
測試 Connection pools 中 connection 的有效性预厌。

當(dāng)然最好的辦法是同時綜合使用上述3種方法阿迈,下面就 DBCP、C3P0 和 simple jdbc dataSource 分別做一說明轧叽,假設(shè) wait_timeout 為默認(rèn)的8小時
DBCP 增加以下配置信息:


復(fù)制代碼

validationQuery = "select 1"testWhileIdle = "true"http://some positive integertimeBetweenEvictionRunsMillis = 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"


復(fù)制代碼

C3P0 增加以下配置信息:


復(fù)制代碼

//獲取connnection時測試是否有效testConnectionOnCheckin = true//自動測試的table名稱automaticTestTable=C3P0TestTable//set to something much less than wait_timeout, prevents connections from going staleidleConnectionTestPeriod = 18000//set to something slightly less than wait_timeout, preventing 'stale' connections from being handed outmaxIdleTime = 25000//if you can take the performance 'hit', set to "true"testConnectionOnCheckout = true


復(fù)制代碼

simple jdbc dataSource 增加以下配置信息:


復(fù)制代碼

Pool.PingQuery = select 1Pool.PingEnabled = truePool.PingConnectionsOlderThan = 0//對于空閑的連接一個小時檢查一次Pool.PingConnectionsNotUsedFor = 3600000


復(fù)制代碼

其他方案(不推薦)
  對于 MySQL5 之前的版本苗沧,如 Mysql4.x,只需要修改連接池配置中的 URL炭晒,添加一個參數(shù):autoReconnect=true(如jdbc:mysql://hostaddress:3306/schemaname?autoReconnect=true)待逞,如果是 MySQL5 及以后的版本,則需要修改 my.cnf(或者my.ini) 文件网严,在 [mysqld] 后面添加上:
wait_timeout = n

interactive-timeout = n

其中 n 為服務(wù)器關(guān)閉交互式連接前等待活動的秒數(shù)识樱。可是就部署而言每次修改 my.ini 比較麻煩震束,而且 n 等于多少才是合適的值呢怜庸? 所以并不推薦這個解決辦法。)

  1. Apache-DBCP

? BasicDataSource 相關(guān)的參數(shù)說明

dataSource: 要連接的 datasource (通常我們不會定義在 server.xml)
defaultAutoCommit: 對于事務(wù)是否 autoCommit, 默認(rèn)值為 true
defaultReadOnly: 對于數(shù)據(jù)庫是否只能讀取, 默認(rèn)值為 false
driverClassName:連接數(shù)據(jù)庫所用的 JDBC Driver Class,
maxActive: 可以從對象池中取出的對象最大個數(shù)垢村,為0則表示沒有限制割疾,默認(rèn)為8
maxIdle: 最大等待連接中的數(shù)量,設(shè) 0 為沒有限制 (對象池中對象最大個數(shù))
minIdle:對象池中對象最小個數(shù)
maxWait: 最大等待秒數(shù), 單位為 ms, 超過時間會丟出錯誤信息
password: 登陸數(shù)據(jù)庫所用的密碼
url: 連接數(shù)據(jù)庫的 URL
username: 登陸數(shù)據(jù)庫所用的帳號
validationQuery: 驗證連接是否成功, SQL SELECT 指令至少要返回一行
removeAbandoned: 是否自我中斷, 默認(rèn)是 false
removeAbandonedTimeout: 幾秒后會自我中斷, removeAbandoned 必須為 true
logAbandoned: 是否記錄中斷事件, 默認(rèn)為 false
minEvictableIdleTimeMillis:大于0 ,進行連接空閑時間判斷嘉栓,或為0宏榕,對空閑的連接不進行驗證;默認(rèn)30分鐘
timeBetweenEvictionRunsMillis:失效檢查線程運行時間間隔侵佃,如果小于等于0麻昼,不會啟動檢查線程,默認(rèn)-1
testOnBorrow:取得對象時是否進行驗證趣钱,檢查對象是否有效涌献,默認(rèn)為false
testOnReturn:返回對象時是否進行驗證,檢查對象是否有效首有,默認(rèn)為false
testWhileIdle:空閑時是否進行驗證燕垃,檢查對象是否有效,默認(rèn)為false
? 在使用DBCP的時候井联,如果使用默認(rèn)值卜壕,則數(shù)據(jù)庫連接因為某種原因斷掉后,再從連接池中取得連接又不進行驗證烙常,這時取得的連接實際上就會是無效的數(shù)據(jù)庫連接轴捎。因此為了防止獲得的數(shù)據(jù)庫連接失效鹤盒,在使用的時候最好保證:

username: 登陸數(shù)據(jù)庫所用的帳號
validationQuery:SELECT COUNT(*) FROM DUAL
testOnBorrow、testOnReturn侦副、testWhileIdle:最好都設(shè)為true
minEvictableIdleTimeMillis:大于0 侦锯,進行連接空閑時間判斷,或為0秦驯,對空閑的連接不進行驗證
timeBetweenEvictionRunsMillis:失效檢查線程運行時間間隔尺碰,如果小于等于0,不會啟動檢查線程
? PS:在構(gòu)造GenericObjectPool [BasicDataSource在其createDataSource () 方法中也會使用GenericObjectPool] 時译隘,會生成一個內(nèi)嵌類Evictor亲桥,實現(xiàn)自Runnable接口。如果timeBetweenEvictionRunsMillis大于0固耘,每過timeBetweenEvictionRunsMillis毫秒Evictor會調(diào)用evict()方法题篷,檢查對象的閑置時間是否大于 minEvictableIdleTimeMillis毫秒(_minEvictableIdleTimeMillis小于等于0時則忽略,默認(rèn)為30分鐘)厅目,是則銷毀此對象番枚,否則就激活并校驗對象,然后調(diào)用ensureMinIdle方法檢查確保池中對象個數(shù)不小于_minIdle璧瞬。在調(diào)用returnObject方法把對象放回對象池户辫,首先檢查該對象是否有效,然后調(diào)用PoolableObjectFactory 的passivateObject方法使對象處于非活動狀態(tài)嗤锉。再檢查對象池中對象個數(shù)是否小于maxIdle渔欢,是則可以把此對象放回對象池,否則銷毀此對象

? 上述特性的可設(shè)置性已在代碼中驗證瘟忱,具體性能是否能實現(xiàn)有待實際驗證

  1. C3P0

? C3P0的官方example中使用的數(shù)據(jù)源為ComboPooledDataSource奥额,網(wǎng)上一篇文章詳細介紹了C3P0連接池配置中各項含義[這些配置項的含義在下載解壓c3p0的壓縮包之后目錄的doc\index.html中的Configuration部分也有詳細的介紹,這里偷下懶:P]访诱,現(xiàn)摘錄如下:

<c3p0-config>
<default-config>

<property name="acquireIncrement">3</property>


<property name="acquireRetryAttempts">30</property>


<property name="acquireRetryDelay">1000</property>


<property name="autoCommitOnClose">false</property>

<property name="automaticTestTable">Test</property>

<property name="breakAfterAcquireFailure">false</property>

<property name="checkoutTimeout">100</property>

<property name="connectionTesterClassName"></property>

<property name="factoryClassLocation">null</property>

<property name="forceIgnoreUnresolvedTransactions">false</property>


<property name="idleConnectionTestPeriod">60</property>


<property name="initialPoolSize">3</property>


<property name="maxIdleTime">60</property>


<property name="maxPoolSize">15</property>

<property name="maxStatements">100</property>


<property name="maxStatementsPerConnection"></property>

<property name="numHelperThreads">3</property>

<property name="overrideDefaultUser">root</property>


<property name="overrideDefaultPassword">password</property>


<property name="password"></property>

<property name="preferredTestQuery">select id from test where id=1</property>


<property name="propertyCycle">300</property>

<property name="testConnectionOnCheckout">false</property>


<property name="testConnectionOnCheckin">true</property>


<property name="user">root</property>

<property name="usesTraditionalReflectiveProxies">false</property>

<property name="automaticTestTable">con_test</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">25</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">0</property>
<user-overrides user="swaldman">
</user-overrides>
</default-config>
<named-config name="dumbTestConfig">
<property name="maxStatements">200</property>
<user-overrides user="poop">
<property name="maxStatements">300</property>
</user-overrides>
</named-config>
</c3p0-config>

? 上述特性的可設(shè)置性已在代碼中驗證垫挨,具體性能是否能實現(xiàn)有待實際驗證

? 從配置項的內(nèi)容來看,C3P0和DBCP都有比較詳細的有關(guān)連接檢測保證的配置触菜,我們可以看到C3P0可以控制數(shù)據(jù)源內(nèi)加載的PreparedStatements數(shù)量九榔,并且可以設(shè)置幫助線程的數(shù)量來提升JDBC操作的速度,這些是DBCP未提供的涡相;另外從網(wǎng)絡(luò)上的評價來看哲泊,DBCP出現(xiàn)Bug的頻率要大于C3P0,不過這一點有待于我們自己實際的檢測催蝗。

  1. Proxool

? Proxool的使用和dbcp以及c3p0稍有不同切威,我們需要并且只需要在使用基本的java.sql.DriverManager之前加載org.logicalcobwebs.proxool.ProxoolDriver驅(qū)動類,并且按照proxool定義的url格式 ["proxool." + alias + ":" + driverClass + ":" + driverUrl ,其中alias是為連接池自定義的別名] 來獲得connection丙号;具體的可以參看proxool doc下的UserGuide先朦,或本文所附的示例代碼缰冤。下面對連接池的特性配置作詳細說明 [這個是自己翻譯的,不一定準(zhǔn)確喳魏,有問題時請參看doc下的Properties ~]棉浸。

n fatal-sql-exception

以逗號隔開的異常列表,當(dāng)設(shè)置了此項之后截酷,每當(dāng)出現(xiàn)SQLException時都將與列表中異常項作比較涮拗,如果匹配則認(rèn)為出現(xiàn)fatal異常乾戏,這將導(dǎo)致connection被丟棄迂苛,并且不論出現(xiàn)任何情況該異常將被重拋一次以通知用戶發(fā)生的情況。默認(rèn)值為null

n fatal-sql-exception-wrapper-class

如果配置了fatal-sql-exception鼓择,則默認(rèn)的操作是丟 棄引起SQLException的原因而只是拋出原始異常三幻。使用fatal-sql-exception-wrapper-class這個特性可以將 SQLException包裝到繼承SQLException或RunTimeException的任何異常類里。Proxool提供了兩個類供使用 FatalSQLException和FatalRunTimeException呐能;使用這兩個類的話就將該選項設(shè)置為 'org.logicalcobwebs.proxool.FatalSQLException'或者 'org.logicalcobwebs.proxool.FatalRuntimeException'念搬。默認(rèn)值為null

n house-keeping-sleep-time

proxool自動偵察各個連接狀態(tài)的時間間隔(毫秒),偵察到空閑的連接就馬上回收,超時的銷毀,默認(rèn)值為30秒

n house-keeping-test-sql

如果偵察線程發(fā)現(xiàn)閑置連接摆出,則會使用這個SQL語句來對這些連接進行檢查朗徊;這項設(shè)置的語句應(yīng)該能夠被很快的執(zhí)行,例如查詢當(dāng)前時間 [info.setProperty("proxool.house-keeping-test-sql", "select CURRENT_DATE");] 偎漫。如果不設(shè)置則該選項被忽略

n injectable-connection-interface爷恳、injectable-statement-interface、injectable-prepared-statement-interface象踊、injectable-callable-statement-interface

n jmx

如果此項設(shè)為true温亲,則連接池將被以名稱"Proxool:type=Pool, name=<alias>"注冊為JMS Server的MBean。默認(rèn)值為false

n jmx-agent-id

當(dāng)且僅當(dāng)jmx選項設(shè)為true時使用杯矩,為以逗號分隔的連接持注冊到的JMS代理名稱列表栈虚;如果不設(shè)置則所有注冊的JMX Server都將被使用

n maximum-active-time

線程最大存活時間,超過此時間的線程將被守護線程kill掉史隆,默認(rèn)值為5分鐘

n maximum-connection-count

到數(shù)據(jù)庫的最大連接數(shù)魂务,超過了這個連接,再有請求時泌射,就排在隊列中等候粘姜,最大的等待請求數(shù)由simultaneous-build-throttle決定;默認(rèn)值為15

n maximum-connection-lifetime

連接最大存活時間魄幕,毫秒為單位相艇,默認(rèn)值為4小時

n minimum-connection-count

不管是否被使用都保持開放的最小連接數(shù),默認(rèn)值為5

n overload-without-refusal-lifetime

用來判斷連接池狀態(tài)纯陨,如果在此選項設(shè)置時間內(nèi)(毫秒為單位)拒絕了連接坛芽,則認(rèn)為過負載留储。默認(rèn)值為60秒

n prototype-count

最少保持的空閑連接數(shù),注意與minimum-connection-count區(qū)分咙轩。默認(rèn)值為0

n simultaneous-build-throttle

最大的等待請求數(shù)获讳,默認(rèn)值為10

n test-before-use

如果設(shè)為true則connection在使用前將以house-keeping-test-sql設(shè)置的語句測試,如果測試不通過則該connection被丟棄并會重新分配一個connection活喊。默認(rèn)為false

n test-after-use

如果設(shè)為true則connection在關(guān)閉(放回連接池)前將以house-keeping-test-sql設(shè)置的語句測試丐膝,如果測試不通過connection將被丟棄。默認(rèn)值為false

? 與其它連接池特性的設(shè)置方法不同钾菊,Proxool不提供相應(yīng)的set方法帅矗,所有特性都要以諸如info.setProperty("proxool.jmx", "false");方式設(shè)定

? 上述特性的可設(shè)置性已在代碼中驗證,具體性能是否能實現(xiàn)有待實際驗證

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末煞烫,一起剝皮案震驚了整個濱河市浑此,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌滞详,老刑警劉巖凛俱,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異料饥,居然都是意外死亡蒲犬,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門岸啡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來原叮,“玉大人,你說我怎么就攤上這事凰狞∑茫” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵赡若,是天一觀的道長达布。 經(jīng)常有香客問我,道長逾冬,這世上最難降的妖魔是什么黍聂? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮身腻,結(jié)果婚禮上产还,老公的妹妹穿的比我還像新娘。我一直安慰自己嘀趟,他們只是感情好脐区,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著她按,像睡著了一般牛隅。 火紅的嫁衣襯著肌膚如雪炕柔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天媒佣,我揣著相機與錄音匕累,去河邊找鬼。 笑死默伍,一個胖子當(dāng)著我的面吹牛欢嘿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播也糊,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼炼蹦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了显设?” 一聲冷哼從身側(cè)響起框弛,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捕捂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體斗搞,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡指攒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了僻焚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片允悦。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖虑啤,靈堂內(nèi)的尸體忽然破棺而出隙弛,到底是詐尸還是另有隱情,我是刑警寧澤狞山,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布全闷,位于F島的核電站,受9級特大地震影響萍启,放射性物質(zhì)發(fā)生泄漏总珠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一勘纯、第九天 我趴在偏房一處隱蔽的房頂上張望局服。 院中可真熱鬧,春花似錦驳遵、人聲如沸淫奔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唆迁。三九已至佳鳖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間媒惕,已是汗流浹背系吩。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留妒蔚,地道東北人穿挨。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像肴盏,于是被迫代替她去往敵國和親科盛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理菜皂,服務(wù)發(fā)現(xiàn)贞绵,斷路器,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • 最原始的數(shù)據(jù)庫連接就是我們打開一個連接恍飘,使用過后再關(guān)閉該鏈接來釋放資源榨崩。頻繁的新建打開再關(guān)閉連接對jvm和數(shù)據(jù)庫都...
    野柳閱讀 6,370評論 1 11
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法章母,內(nèi)部類的語法母蛛,繼承相關(guān)的語法,異常的語法乳怎,線程的語...
    子非魚_t_閱讀 31,644評論 18 399
  • application的配置屬性彩郊。 這些屬性是否生效取決于對應(yīng)的組件是否聲明為Spring應(yīng)用程序上下文里的Bea...
    新簽名閱讀 5,374評論 1 27
  • 人海茫茫一面緣,心千轉(zhuǎn)蚪缀,思伊顏秫逝,酒入愁腸情不堪。 七尺青鋒白刃寒询枚,斬情絲违帆,斷情戀,看破紅塵心亦寒哩盲。
    e5f2e147f7a3閱讀 171評論 4 5