我發現 很多人 誤解了這二者。 csdn上也有人提出過這種疑問:java
http://bbs.csdn.net/topics/250061733sql
通過查閱資料和認真分析,我特說明一下這二者概念上的區別。數據庫
我只講兩個關鍵點,明白人一看就懂:緩存
一、二者有根本性的區別,用處不同!工具
1)鏈接池是緩存並託管數據庫鏈接,主要是爲了提升性能。性能
2)而ThreadLocal緩存鏈接,是爲了把同一個數據庫鏈接「分享」給同一個線程的不一樣調用方法。(無論調用哪一個方法,都是使用的同一個鏈接,方便進行「跨方法」的事務控制)url
舉個例子: spa
若是一個請求中涉及多個 DAO 操做,而若是這些DAO中的Connection都是獨立的話,就沒有辦法完成一個事務。可是若是DAO 中的 Connection 是從 ThreadLocal 中得到的(意味着都是同一個對象), 那麼這些 DAO 就會被歸入到同一個 Connection 之下。.net
二、重點要理解「鏈接池」。線程
鏈接池裏面有必定數量的鏈接資源,好比最大20個鏈接。
題外話:若是直接經過 Java原生API 獲取「直連」的話:
(底層方法通常都是這樣寫的:
java.sql.DriverManager.getConnection(url, props);
java.sql.Driver.connect(url, props);
特色是:要傳入url、用戶名和密碼等信息)
這種方式,確定就沒有使用數據庫鏈接池。
使用數據庫鏈接池,一般都是獲得一個所謂的javax.sql.DataSource[接口]的實例對象,它裏面包含了Connection,而且數據庫鏈接池工具類(好比C3P0、JNDI、DBCP等),確定是從新定義了getConnection、closeConnection等方法,因此你每次獲得的Connection,幾乎都不是新創建的鏈接(而是已經創建好並放到緩存裏面的鏈接),你調用closeConnection方法,也不是真正的關閉鏈接(通常都是起到一個標識做用,標識當前鏈接已經使用完畢,歸還給鏈接池,讓這個鏈接處於待分配狀態)【PS:因此說:使用數據庫鏈接池時,仍是要顯式的調用數據庫鏈接池API提供的關閉鏈接的方法】。
理解一下這句話:
不一樣的線程在同一個時間( 或者 同一個線程在多個地方) 從鏈接池中拿到的Connection,確定不是同一個鏈接。(反過來說:不一樣時間的兩個線程,一前一後,則有可能拿到同一個鏈接)。