理解資料庫連線池和ThreadLocal實現的事務控制

Zollty發表於2014-03-17

 

我發現 不少人 誤解了這兩者。 csdn上也有人提出過這種疑問:

http://bbs.csdn.net/topics/250061733

 

經過查閱資料和認真分析,我特說明一下這兩者概念上的區別。

 

我只講兩個關鍵點,明白人一看就懂:

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

   1)連線池是快取並託管資料庫連線,主要是為了提高效能。

   2)而ThreadLocal快取連線,是為了把同一個資料庫連線“分享”給同一個執行緒的不同呼叫方法。(不管呼叫哪個方法,都是使用的同一個連線,方便進行“跨方法”的事務控制)

  舉個例子: 

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

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

 連線池裡面有一定數量的連線資源,比如最大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,肯定不是同一個連線。(反過來講:不同時間的兩個執行緒,一前一後,則有可能拿到同一個連線)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章