通常我們會把事務處理放在業務層。
[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();
能實現一樣的效果
}
上面的黑體部分,就可以實現對事務的統一管理。
[6]改進
上面的方法給人的感覺有點別扭,但是卻能實現事務的統一管理。
我還要繼續改進。
|----------------------------------------------------------------------------------------|
版權聲明 版權所有 @zhyiwww
引用請注明來源 http://www.tkk7.com/zhyiwww
|----------------------------------------------------------------------------------------|
posted on 2010-02-11 15:34
zhyiwww 閱讀(1874)
評論(2) 編輯 收藏 所屬分類:
j2ee