Druid connection holder is null 未解之謎

來源 |?https://www.jianshu.com/p/073daa6b1a37
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í)間過長(zhǎng),超過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è)功能是為了回收長(zhǎng)時(shí)間還沒還到池里的連接,多長(zhǎng)時(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ù)長(zhǎng)時(shí)間未提交,DBA會(huì)把這個(gè)連接kill掉,后面請(qǐng)求會(huì)報(bào)conneciton holder is null
為什么有長(zhǎng)時(shí)間未提交的事務(wù),這個(gè)問題還沒找到原因,從Mysql的innodb_trx和lock表里沒看到有價(jià)值線索,后面想跟蹤事務(wù)和連接來看看有沒有收獲。 連接被kill了,應(yīng)用端會(huì)報(bào)這樣的異常:
Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost. 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. connection holder is null
- 推薦閱讀 -
《架構(gòu)師離職后,成為自由開發(fā)者的第 100 天》
下方二維碼關(guān)注我

互聯(lián)網(wǎng)草根,堅(jiān)持分享技術(shù)、創(chuàng)業(yè)、產(chǎn)品等心得和總結(jié)~

點(diǎn)擊“閱讀原文”,領(lǐng)取 2020 年最新免費(fèi)技術(shù)資料大全
評(píng)論
圖片
表情
