將connection存放在Threadlocal裡和資料庫連線池的區別
1、j2ee的應用中,有一個使用者請求就會啟動一個執行緒。而如果我們把connection放在Threadlocal裡的話,那麼我們的程式只需要一個connection連線資料庫就行了,每個執行緒都是用的connection的一個副本,那為什麼還有必要要資料庫連線池呢?
2、在這種情況下一個副本里的connection執行了關閉操作,其他都沒執行。那麼想問一下真正與資料庫連線的connection什麼時候關閉呢?
3、顯然上面的第一個問題是不成立的,但是希望哪位大俠幫我解釋下。解釋下什麼時候是從資料庫連線池裡取connection而什麼時候獲得的是connection的一個Threadlocal副本?
答覆1:
由於請求中的一個事務涉及多個 DAO 操作,而這些 DAO 中的 Connection
不能從連線池中獲得,如果是從連線池獲得的話,兩個 DAO 就用到了兩個
Connection,這樣的話是沒有辦法完成一個事務的。
DAO 中的 Connection 如果是從 ThreadLocal 中獲得 Connection 的話那
麼這些 DAO 就會被納入到同一個 Connection 之下。當然了,這樣的話,
DAO 中就不能把 Connection 給關了,關掉的話,下一個使用者就不能用了。
如11樓所說,一個事務涉及多個 DAO 操作.
答覆2:
...首先,LZ是概念上的錯誤.什麼是執行緒池,什麼是ThreadLocal???
執行緒池,為避免不必要的建立,銷燬connection而存在的,其中包括活動,等待,最小等屬性,cop3,proxy連線池都可以配置這些玩意;
至於為什麼要用ThreadLocal呢?這個和連線池無關,我認為更多的是和程式本身相關,為了更清楚的說明,我舉個例子
servlet中獲取一個連線.首先,servlet是執行緒安全的嗎?
class MyServlet extends HttpServlet{
private Connection conn;
}
ok,遺憾的告訴你,這個conn並不是安全的,所有請求這個servlet的連線,使用的都是一個Connection,這個就是致命的了.多個人使用同一個連線,算上延遲啥的,天知道資料會成什麼樣.
因此我們要保證Connection對每個請求都是唯一的.這個時候就可以用到ThreadLocal了,保證每個執行緒都有自己的連線.
改為 private ThreadLocal<Connection> ct = new ThreadLocal<Connnection>();
然後從連線池獲取Connection,set到ct中,再get就行了,至於得到的是哪個Connection就是連線池的問題了,你也管不到.