<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>

          面試官:數(shù)據(jù)庫連接池為什么都要用Threadlocal呢?

          共 1984字,需瀏覽 4分鐘

           ·

          2021-06-01 16:39

          你知道的越多,不知道的就越多,業(yè)余的像一棵小草!

          成功路上并不擁擠,因為堅持的人不多。

          編輯:業(yè)余草

          blog.csdn.net/qq_42405666

          推薦:https://www.xttblog.com/?p=5186

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

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

          本人是在學(xué) Threadlocal 的時候,網(wǎng)上大部分人都是說數(shù)據(jù)庫連接池是典型的用了threadloca 的例子,然后我就又查數(shù)據(jù)庫連接池和 threadloca 的關(guān)系,但是,99% 都說 threadlocal 是為了在并發(fā)的情況下,為了保證線程安全,創(chuàng)建了副本什么的,其實這只是 threadlocal 的用法之一,它還有個用法就是確保同一線程之間參數(shù)傳遞的方便(扯遠了)。

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

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

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

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

          而 ThreadLocal 緩存連接,是為了把同一個數(shù)據(jù)庫連接“分享”給同一個線程的不同調(diào)用方法。(不管調(diào)用哪個方法,都是使用的同一個連接,方便進行“跨方法”的事務(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)閉連接(一般都是起到一個標識作用,標識當前連接已經(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ù)庫連接池獲取連接,那肯定拿的是不同的連接,我當前線程和別的線程拿的連接不一樣,那我當前在 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 一份,這樣就互相不干擾了。

          以上是我的個人見解。

          文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。謝謝支持喲 (*^__^*)

          瀏覽 69
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  日韩免费黄色AⅤ电影 | 杨幂久久免费区一区二区 | 在线无码一区二区三区 | 丝袜脚丫丁香五月 | 影音先锋在线视频免费观看 |