Druid連接池源碼解析(4)Connection

1 獲取Connection

DruidDataSource初始化完成后,即可獲取connection與數(shù)據(jù)庫進(jìn)行交互了。
獲取如果有Filter,從filterChain中獲取connection,否則調(diào)用getConnectionDirect()直接獲取。
兩者返回的都是經(jīng)過封裝的DruidPooledConnection,類圖:


DruidPooledConnection.png

看下構(gòu)造函數(shù),需要傳入holder,從中獲取實(shí)際的Connection
擴(kuò)展定義了abandoned、running、disable和close的狀態(tài)
beforeExecute()和afterExecute() 處理running狀態(tài)的修改,影響DataSource中的removeAbandoned(),執(zhí)行中的connection跳過清理
abandoned 在recycle()中影響是否回收
disable和close用處比較多,主要就是標(biāo)記連接是否可用

2 getConnection詳解

getConnectionDirect()方法開始,主要流程:

  • 死循環(huán)開始直到獲取可用鏈接為止
  • 調(diào)用getConnectionInternal獲取DruidPooledConnection
  • 如果testOnBorrow為true,則進(jìn)行對連接進(jìn)行校驗
  • 如果testWhileIdle為true,距離上次激活時間超過timeBetweenEvictionRunsMillis,則進(jìn)行清理。
  • 如果removeAbandoned為true,則會把連接存放在activeConnections中,清理線程會對其定期進(jìn)行處理。

getConnectionInternal()方法,主要流程:

  • 檢查等待線程數(shù)和錯誤線程數(shù),超過設(shè)置了,拋異常
  • createScheduler存在且可用,標(biāo)志位createDirect置為true,重新開始循環(huán),進(jìn)入直接創(chuàng)建連接流程,創(chuàng)建新的物理連接和holder,加鎖校驗連接數(shù)有沒有超設(shè)置,超過便discord,否則即完成創(chuàng)建
  • 調(diào)用pollLast(nanos)-有超時,或者 takeLast()獲取holder,如果獲取holder失敗,構(gòu)建異常消息,拋異常
  • 否則,以holder為參new一個DruidPooledConnection返回

takeLast()主要就是從連接數(shù)組中獲取最后一個可用的返回

獲取到鏈接之后,就可以調(diào)用conn.prepareStatement來執(zhí)行sql了

3 連接回收

DruidPooledConnection實(shí)現(xiàn)了JDBC的close方法,
從holder中獲取Datasource,判斷當(dāng)前線程是否歸屬線程,不是的話,就加鎖關(guān)閉
否則直接進(jìn)行關(guān)閉
分發(fā)當(dāng)前連接關(guān)閉的事件到ConnectionEventListener
最終都到recycle()方法中進(jìn)行回收,而不是真正的關(guān)閉,主要流程如下:
同樣判斷當(dāng)前線程是否歸屬線程,不是的話,就加鎖操作
將當(dāng)前線程從活躍線程組 activeConnections 中移除,主要是方便后面的丟棄或者回收的工作。
然后檢查是否需要進(jìn)行回滾,不需要繼續(xù)往下走。
reset 當(dāng)前 connection 的 holder 的相關(guān)配置。
接下來是對各項信息進(jìn)行檢查,主要是看連接是否還可以重用。
鎖住然后進(jìn)行真正的回收工作,這里回收交給了 putLast 方法。
putLast 呼應(yīng)前面的takeLast,就是把連接放回connections數(shù)組中

4 總結(jié)

獲取和回收連接的過程中,定義了一大堆狀態(tài)和計數(shù)器,主要用于統(tǒng)計和各種加鎖的場景,鎖的粒度已經(jīng)控制得非常精細(xì)了。比想象地要復(fù)雜很多,鎖的粒度精細(xì)化有助于提高并發(fā)場景的性能,但是帶來的代碼復(fù)雜度的提升不是一點(diǎn)點(diǎn)。實(shí)際工程中,不僅要平衡兩者,還要對自己加鎖的操作,有100%的確信度。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容