ThreadLocal中放置connection, 保證事務中的DAO類擷取的都是同一個connection,這樣才保證事務。
下面是網上找到的一個具體的例子http://www.pin5i.com/showtopic-26854.html
-----------------------------------------------------------------------------------
通常我們會把交易處理放在業務層。
[1]引子
比如:
商務邏輯方法
- public A bussinessMethod(){
- DaoA a = new DaoA();
- a.udpate();
- DaoB b = new DaoB();
- b.update;
- }
複製代碼
假設,上面的事務是自動認可的。
那麼,我們就可以什麼不考慮。但是有一個問題,建立DAO對象的時候兩個對象用的是不同的Connection對象。
再假定我們的取得串連的代碼是
- public Connection getConnection(String username, String password)
- throws SQLException {
- Connection con = DriverManager
- .getConnection(conStr, username, password);
- return con;
- }
複製代碼
這個方法的一個調用。
那麼如果,我們需要自己控制事務的開始和結束。
如何控制呢。
也許又有了新的方法
- public A bussinessMethod(){
- DaoA a = new DaoA();
- a.beginTx();
- a.udpate();
- a.endTx();
- a.close();
- DaoB b = new DaoB();
- b.beginTx();
- b.update;
- b.endTx();
- b.close();
- }
複製代碼
這樣我們就控制了事務,並且我們也只有這樣才能實現,因為,不同的DAO取得的是不同的Connection對象。
[2]問題
那麼怎麼才能實現兩個或多個DAO用同一個事務來控制呢?
首先就要解決一個根本問題,我們在一個事務中,不同的DAO取得的是同一個Connection,這個要怎麼實現呢。我們想到了TheadLocal.
[3]方案
因為當一個商務邏輯要對多個DAO進行處理的時候,此操作屬於同一個線程內。所以,我們希望能把此Connection放線上程內,或者和線程有關聯。
第一個方案,可以用Map來使現。
就是Map<Thread,Connection>
但是這個map維護起來比較麻煩,如果一直put的話,那麼這個map隨著系統的運行就會越來越大。
第二個方案,就是用ThreadLocal
在任何一個線程內都可以用ThreadLocal來儲存一個變數的copy,這樣,如果此對象存在,就可以直接取用。
如果把Connection存在ThreadLocal也一樣。
所以,在同一個線程內,就可以保證取得到的是同一個Connection.
[4]實現
- private static ThreadLocal<Connection> localCon = new ThreadLocal<Connection>();
- public final static Connection getConnection() throws SQLException {
-
- Connection con = localCon.get();
-
- if(con==null||con.isClosed()){
- con = new OracleJdbcDatasource().getConnection();
-
- localCon.set(con);
- }
-
- return con;
- }
複製代碼
這樣就實現了上面的問題。
[5]新的交易管理
- public A bussinessMethod(){
- DaoA a = new DaoA();
- DaoB b = new DaoB();
- a.beginTx();
- a.udpate();
- b.beginTx();
- b.update;
- a.endTx();
- a.close();
- // b.endTx();
- // b.close();
- 能實現一樣的效果
-
- }
複製代碼
上面的黑體部分,就可以實現對事務的統一管理。