數(shù)據(jù)庫(kù)連接池為啥要用 ThreadLocal?不用會(huì)怎么樣?
這個(gè)問(wèn)題我疑問(wèn)了很久很久,主要如下截圖。

一個(gè)連接對(duì)應(yīng)一個(gè)事務(wù),多個(gè)連接的事務(wù)是不一樣的,先大概了解一下,往下看??
本人是在學(xué)threadlocal的時(shí)候,網(wǎng)上大部分人都是說(shuō)數(shù)據(jù)庫(kù)連接池是典型的用了threadloca的例子,然后我就又查數(shù)據(jù)庫(kù)連接池和threadloca的關(guān)系。
回歸正題,還是拿上面的圖來(lái)說(shuō)事。。。。
我只講兩個(gè)關(guān)鍵點(diǎn),明白人一看就懂:
1、兩者有根本性的區(qū)別,用處不一樣!
2、重點(diǎn)要理解“連接池”。
連接池里面有一定數(shù)量的連接資源,比如最大20個(gè)連接。
題外話(huà):如果直接通過(guò) Java原生API 獲取“直連”的話(huà):
底層方法一般都是這樣寫(xiě)的:
java.sql.DriverManager.getConnection(url, props);
java.sql.Driver.connect(url, props);
這種方式,肯定就沒(méi)有使用數(shù)據(jù)庫(kù)連接池。
使用數(shù)據(jù)庫(kù)連接池,通常都是得到一個(gè)所謂的javax.sql.DataSource[接口]的實(shí)例對(duì)象,它里面包含了Connection,并且數(shù)據(jù)庫(kù)連接池工具類(lèi)(比如C3P0、JNDI、DBCP等),肯定是重新定義了getConnection、closeConnection等方法。
所以你每次得到的Connection,幾乎都不是新建立的連接(而是已經(jīng)建立好并放到緩存里面的連接),你調(diào)用closeConnection方法,也不是真正的關(guān)閉連接(一般都是起到一個(gè)標(biāo)識(shí)作用,標(biāo)識(shí)當(dāng)前連接已經(jīng)使用完畢,歸還給連接池,讓這個(gè)連接處于待分配狀態(tài))
PS:所以說(shuō):使用數(shù)據(jù)庫(kù)連接池時(shí),還是要顯式的調(diào)用數(shù)據(jù)庫(kù)連接池API提供的關(guān)閉連接的方法。
不同的線(xiàn)程在同一個(gè)時(shí)間( 或者 同一個(gè)線(xiàn)程在多個(gè)地方)從連接池中拿到的Connection,肯定不是同一個(gè)連接。(反過(guò)來(lái)講:不同時(shí)間的兩個(gè)線(xiàn)程,一前一后,則有可能拿到同一個(gè)連接)
總結(jié):
再好好理解一下上面的一段話(huà),我再最后解釋億下。。。
首先,我們?yōu)榱吮苊鈫我粩?shù)據(jù)庫(kù)連接的創(chuàng)建和關(guān)閉耗費(fèi)時(shí)間和性能,引入了數(shù)據(jù)庫(kù)連接池,提前創(chuàng)建好了n條連接放入池中,如果是單線(xiàn)程情況下,那這樣挺好的。
那如果是多線(xiàn)程情況下呢?
還是上面那段話(huà),假設(shè)同一時(shí)間多個(gè)線(xiàn)程從數(shù)據(jù)庫(kù)連接池獲取連接,那肯定拿的是不同的連接,我當(dāng)前線(xiàn)程和別的線(xiàn)程拿的連接不一樣,那我當(dāng)前在crud的時(shí)候,不在一個(gè)事務(wù)之內(nèi)。
假設(shè)不同時(shí)間的多個(gè)線(xiàn)程要從數(shù)據(jù)庫(kù)連接池拿連接,那這個(gè)時(shí)候就可能拿到的是同一個(gè)連接了,那我多個(gè)線(xiàn)程線(xiàn)程拿到的是同一個(gè)連接,也就是說(shuō)在多個(gè)線(xiàn)程在同一個(gè)事務(wù)之內(nèi),線(xiàn)程a執(zhí)行了插入還沒(méi)來(lái)得及提交,線(xiàn)程b此時(shí)來(lái)了個(gè)更新,在線(xiàn)程a還未操作完之前,線(xiàn)程b更新完了后,直接把連接給close了,線(xiàn)程a插了一半發(fā)現(xiàn)插不了了。。。
為了確保不同時(shí)間多個(gè)線(xiàn)程可能拿到的是同一個(gè)連接,那么此時(shí)threadlocal閃亮登場(chǎng),就算我拿的是“同一個(gè)連接”,在引入了threadlocal后,每個(gè)線(xiàn)程之間都會(huì)創(chuàng)建獨(dú)立的連接副本,將collection各自copy一份,這樣就互相不干擾了。
原文鏈接:https://blog.csdn.net/qq_42405666/article/details/108258820
正文結(jié)束
1.不認(rèn)命,從10年流水線(xiàn)工人,到谷歌上班的程序媛,一位湖南妹子的勵(lì)志故事
3.從零開(kāi)始搭建創(chuàng)業(yè)公司后臺(tái)技術(shù)棧
5.37歲程序員被裁,120天沒(méi)找到工作,無(wú)奈去小公司,結(jié)果懵了...
一個(gè)人學(xué)習(xí)、工作很迷茫?
點(diǎn)擊「閱讀原文」加入我們的小圈子!

