<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Druid connection holder is null 未解之謎

          共 2494字,需瀏覽 5分鐘

           ·

          2020-09-25 19:31


          來源 |?https://www.jianshu.com/p/073daa6b1a37

          系統(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í)間過長(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)這樣的異常:
          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ù)。

          - 推薦閱讀 -


          架構(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ù)資料大全

          ↓↓↓?
          瀏覽 47
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久激情内射婷内射蜜桃 | 亚洲黄色视频在线 | 天天日天天插天天操 | 国产女主播在线 | 成人黄色在线 |