1. 數(shù)據(jù)庫連接池為啥要用 ThreadLocal?不用會怎么樣?

        共 2215字,需瀏覽 5分鐘

         ·

        2021-06-15 21:33

        上一篇:深夜看了張一鳴的微博,讓我越想越后怕


        這個問題我疑問了很久很久,主要如下截圖。

        一個連接對應(yīng)一個事務(wù),多個連接的事務(wù)是不一樣的,先大概了解一下,往下看??

        本人是在學(xué)threadlocal的時候,網(wǎng)上大部分人都是說數(shù)據(jù)庫連接池是典型的用了threadloca的例子,然后我就又查數(shù)據(jù)庫連接池和threadloca的關(guān)系。

        但是,99%都說threadlocal是為了在并發(fā)的情況下,為了保證線程安全,創(chuàng)建了副本什么的,其實這只是threadlocal的用法之一,它還有個用法就是確保同一線程之間參數(shù)傳遞的方便(扯遠(yuǎn)了)

        回歸正題,還是拿上面的圖來說事。。。。

        我只講兩個關(guān)鍵點,明白人一看就懂:

        1、兩者有根本性的區(qū)別,用處不一樣!

        連接池是緩存并托管數(shù)據(jù)庫連接,主要是為了提高性能。

        而ThreadLocal緩存連接,是為了把同一個數(shù)據(jù)庫連接“分享”給同一個線程的不同調(diào)用方法。(不管調(diào)用哪個方法,都是使用的同一個連接,方便進(jìn)行“跨方法”的事務(wù)控制)

        舉個栗子:

        如果一個請求中涉及多個 DAO 操作,而如果這些DAO中的Connection都是獨立的話,就沒有辦法完成一個事務(wù)。但是如果DAO 中的 Connection 是從 ThreadLocal 中獲得的(意味著都是同一個對象), 那么這些 DAO 就會被納入到同一個 Connection 之下。

        2、重點要理解“連接池”。

        連接池里面有一定數(shù)量的連接資源,比如最大20個連接。

        題外話:如果直接通過 Java原生API 獲取“直連”的話:

        底層方法一般都是這樣寫的:

        java.sql.DriverManager.getConnection(url, props);

        java.sql.Driver.connect(url, props);
        特點是:要傳入url、用戶名和密碼等信息)

        這種方式,肯定就沒有使用數(shù)據(jù)庫連接池。

        使用數(shù)據(jù)庫連接池,通常都是得到一個所謂的javax.sql.DataSource[接口]的實例對象,它里面包含了Connection,并且數(shù)據(jù)庫連接池工具類(比如C3P0、JNDI、DBCP等),肯定是重新定義了getConnection、closeConnection等方法。

        所以你每次得到的Connection,幾乎都不是新建立的連接(而是已經(jīng)建立好并放到緩存里面的連接),你調(diào)用closeConnection方法,也不是真正的關(guān)閉連接(一般都是起到一個標(biāo)識作用,標(biāo)識當(dāng)前連接已經(jīng)使用完畢,歸還給連接池,讓這個連接處于待分配狀態(tài))

        PS:所以說:使用數(shù)據(jù)庫連接池時,還是要顯式的調(diào)用數(shù)據(jù)庫連接池API提供的關(guān)閉連接的方法。

        理解一下這句話:

        不同的線程在同一個時間( 或者 同一個線程在多個地方)從連接池中拿到的Connection,肯定不是同一個連接。(反過來講:不同時間的兩個線程,一前一后,則有可能拿到同一個連接)

        總結(jié):

        再好好理解一下上面的一段話,我再最后解釋億下。。。

        首先,我們?yōu)榱吮苊鈫我粩?shù)據(jù)庫連接的創(chuàng)建和關(guān)閉耗費時間和性能,引入了數(shù)據(jù)庫連接池,提前創(chuàng)建好了n條連接放入池中,如果是單線程情況下,那這樣挺好的。

        那如果是多線程情況下呢?

        還是上面那段話,假設(shè)同一時間多個線程從數(shù)據(jù)庫連接池獲取連接,那肯定拿的是不同的連接,我當(dāng)前線程和別的線程拿的連接不一樣,那我當(dāng)前在crud的時候,不在一個事務(wù)之內(nèi)。

        假設(shè)不同時間的多個線程要從數(shù)據(jù)庫連接池拿連接,那這個時候就可能拿到的是同一個連接了,那我多個線程線程拿到的是同一個連接,也就是說在多個線程在同一個事務(wù)之內(nèi),線程a執(zhí)行了插入還沒來得及提交,線程b此時來了個更新,在線程a還未操作完之前,線程b更新完了后,直接把連接給close了,線程a插了一半發(fā)現(xiàn)插不了了。。。

        為了確保不同時間多個線程可能拿到的是同一個連接,那么此時threadlocal閃亮登場,就算我拿的是“同一個連接”,在引入了threadlocal后,每個線程之間都會創(chuàng)建獨立的連接副本,將collection各自copy一份,這樣就互相不干擾了。

        原文鏈接:https://blog.csdn.net/qq_42405666/article/details/108258820

        感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!小編到你上高速。


            · END ·
        最后,關(guān)注公眾號互聯(lián)網(wǎng)架構(gòu)師,在后臺回復(fù):2T,可以獲取我整理的 Java 系列面試題和答案,非常齊全。


        正文結(jié)束


        推薦閱讀 ↓↓↓

        1.不認(rèn)命,從10年流水線工人,到谷歌上班的程序媛,一位湖南妹子的勵志故事

        2.如何才能成為優(yōu)秀的架構(gòu)師?

        3.從零開始搭建創(chuàng)業(yè)公司后臺技術(shù)棧

        4.程序員一般可以從什么平臺接私活?

        5.37歲程序員被裁,120天沒找到工作,無奈去小公司,結(jié)果懵了...

        6.IntelliJ IDEA 2019.3 首個最新訪問版本發(fā)布,新特性搶先看

        7.漫畫:程序員相親圖鑒,笑屎我了~

        8.15張圖看懂瞎忙和高效的區(qū)別!

        一個人學(xué)習(xí)、工作很迷茫?


        點擊「閱讀原文」加入我們的小圈子!

        瀏覽 41
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
          
          

            1. 爱搞网在线观看 | 成人免费A片免费免费 | 综合中文字幕 | 大尺度做爰呻吟舌吻女女漫画 | 韩国伦理视频在线 |