Druid connection holder is null未解之謎

系統(tǒng)中出現(xiàn)過幾次connection holder is null問題舵稠,有的已解決深员,有的未解決,記錄如下干像。

首先說先druid連接池的實(shí)現(xiàn):

  • DruidPooledConnection是一個(gè)靜態(tài)代理帅腌,持有ConnectionHolder, connection Holder里持有具體的connection對(duì)象, 在執(zhí)行druidPooledConnection的所有和數(shù)據(jù)庫相關(guān)方法時(shí)麻汰,都會(huì)先調(diào)用checkState()判斷connection holder是否為null速客,如果是null就拋connection holder is null的異常。

  • 那connection holder是什么時(shí)候賦值以及什么時(shí)候置成null的五鲫?
    在Datasource.getConnection()獲取連接的時(shí)候溺职,是從池里取出緩存的connection holder對(duì)象,druid是用一個(gè)數(shù)組緩存connection holder對(duì)象,每次都是從最后一個(gè)取浪耘,還的時(shí)候也是放到最后乱灵,這樣保證位于數(shù)組最后的連接會(huì)經(jīng)常處于使用狀態(tài),當(dāng)然這中間會(huì)有鎖的使用以及池里沒線程了通知任務(wù)線程去創(chuàng)建新連接七冲。
    Datasource.getConnection()從池里拿出connection holder后痛倚,然后new一個(gè)druidPooledConnection去包裝connection holder,所有每次看到都是不同的druidPooledConnection對(duì)象澜躺。

第一次:系統(tǒng)中事務(wù)執(zhí)行時(shí)間過長蝉稳,超過60秒,后面導(dǎo)致有的請(qǐng)求會(huì)報(bào)connection holder is null掘鄙。

  • 拿出來的connection holder肯定不為null颠区,項(xiàng)目中報(bào)connection holder is null,說明是在使用過程中connection holder被置成null了通铲,很大概率是被別的線程置成null了,因?yàn)楸揪€程只有在事務(wù)提交后還連接的時(shí)候才置null器贩,在github issue上颅夺,作者也反復(fù)強(qiáng)調(diào)連接不要跨線程使用。而druid真的就有跨線程操作連接的地方蛹稍,就是remove abandoned connection功能吧黄,這個(gè)功能是為了回收長時(shí)間還沒還到池里的連接,多長時(shí)間看你設(shè)置唆姐,而我們項(xiàng)目設(shè)置的60秒沒還就強(qiáng)制回收拗慨,這樣就會(huì)報(bào)上面的錯(cuò)誤了。

  • 建議在生產(chǎn)環(huán)境關(guān)閉remove abandoned功能奉芦,如果數(shù)據(jù)庫負(fù)載不重的話赵抢,可以開啟testOnBorrow。 testWhileIde不建議開声功,因?yàn)椴l(fā)請(qǐng)求多的話烦却,數(shù)組后面的連接都不是idle狀態(tài),開沒開testWhileIdle沒啥區(qū)別先巴。

第二次系統(tǒng)中有的事務(wù)長時(shí)間未提交其爵,DBA會(huì)把這個(gè)連接kill掉,后面請(qǐng)求會(huì)報(bào)conneciton holder is null

  • 為什么有長時(shí)間未提交的事務(wù)伸蚯,這個(gè)問題還沒找到原因摩渺,從Mysql的innodb_trx和lock表里沒看到有價(jià)值線索,后面想跟蹤事務(wù)和連接來看看有沒有收獲剂邮。
  • 連接被kill了摇幻,應(yīng)用端會(huì)報(bào)這樣的異常:
  1. Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
  2. com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure. The last packet successfully received from the server was 20,840 milliseconds ago. The last packet sent successfully to the server was 20,840 milliseconds ago.
  3. connection holder is null

前面2個(gè)異常很好理解,tcp連接斷了,應(yīng)用端讀不到數(shù)據(jù)報(bào)錯(cuò)囚企,然后druid捕獲到異常丈咐,要去判斷這個(gè)異常是可恢復(fù)異常還是不可恢復(fù)異常。因?yàn)檎驹谶B接池的角度來說龙宏,數(shù)據(jù)庫拋異常太普遍了棵逊,可能是唯一索引重復(fù)也可能是連接斷了,對(duì)于不同的異常處理方式也是不一樣的银酗,唯一索引重復(fù)需要調(diào)用connection.rollback()辆影,然后再把連接還到池里,因?yàn)檫@個(gè)連接還是好的黍特,不影響下次繼續(xù)使用蛙讥。而連接斷了,則要把這個(gè)連接踢出去灭衷,druid用了ExceptionSorter來判斷這個(gè)異常是不是不可恢復(fù)異常次慢,在轉(zhuǎn)換異常的時(shí)候要用當(dāng)前連接獲取數(shù)據(jù)庫的metadata,而當(dāng)前連接已經(jīng)斷了翔曲,所以報(bào)connection holder is null迫像。
但是這個(gè)connection holder is null只會(huì)報(bào)一次,和項(xiàng)目中大量報(bào)connection holder is null不是一個(gè)東西瞳遍,目前還沒找到原因闻妓。而這個(gè)問題在本地卻重現(xiàn)不了。

PS:數(shù)據(jù)庫有一個(gè)設(shè)置 rollback_on_timeout掠械,默認(rèn)是off由缆,這個(gè)值是說當(dāng)事務(wù)超時(shí)(如超過50秒還沒獲取到鎖),默認(rèn)off是回滾最后一條sql語句猾蒂,on是回滾整個(gè)事務(wù)均唉。這個(gè)值一般不需要設(shè)置成on,交由應(yīng)用去處理肚菠,應(yīng)用在獲取不到 can't acquire lock的時(shí)候浸卦,一般會(huì)去調(diào)connection.rollback(),當(dāng)然前提是要你的應(yīng)用開啟事務(wù)案糙。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末限嫌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子时捌,更是在濱河造成了極大的恐慌怒医,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奢讨,死亡現(xiàn)場(chǎng)離奇詭異稚叹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門扒袖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塞茅,“玉大人,你說我怎么就攤上這事季率∫笆荩” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵飒泻,是天一觀的道長鞭光。 經(jīng)常有香客問我,道長泞遗,這世上最難降的妖魔是什么惰许? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮史辙,結(jié)果婚禮上汹买,老公的妹妹穿的比我還像新娘。我一直安慰自己聊倔,他們只是感情好卦睹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著方库,像睡著了一般。 火紅的嫁衣襯著肌膚如雪障斋。 梳的紋絲不亂的頭發(fā)上纵潦,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音垃环,去河邊找鬼邀层。 笑死,一個(gè)胖子當(dāng)著我的面吹牛遂庄,可吹牛的內(nèi)容都是我干的寥院。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼涛目,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼秸谢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起霹肝,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤估蹄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后沫换,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體臭蚁,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了垮兑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冷尉。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖系枪,靈堂內(nèi)的尸體忽然破棺而出雀哨,到底是詐尸還是另有隱情,我是刑警寧澤嗤无,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布震束,位于F島的核電站,受9級(jí)特大地震影響当犯,放射性物質(zhì)發(fā)生泄漏垢村。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一嚎卫、第九天 我趴在偏房一處隱蔽的房頂上張望嘉栓。 院中可真熱鬧,春花似錦拓诸、人聲如沸侵佃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馋辈。三九已至,卻和暖如春倍谜,著一層夾襖步出監(jiān)牢的瞬間迈螟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來泰國打工尔崔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留答毫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓季春,卻偏偏與公主長得像洗搂,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子载弄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

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