JTA事務(wù)的嵌套
由于前兩篇帖子都是關(guān)于事務(wù)的討論 (J2EE中的事務(wù)處理
、 事務(wù)服務(wù)淺析),沒有討論到事務(wù)嵌套時(shí)的解決辦法,這兩天一直在琢磨,如何才能高效、靈活的解決事務(wù)的嵌套問題呢? 既然web容器可以判斷當(dāng)前方法是否處在事務(wù)中(JTA事務(wù)中提交java.sql.Connection.commit()會(huì)報(bào)錯(cuò)),那么它是如何判斷的呢?帶著這個(gè)疑問,追查了一下resin容器源碼的事務(wù)部分,發(fā)現(xiàn)了一個(gè)類:javax.transaction.Status,用來標(biāo)明事務(wù)狀態(tài)代碼,而javax.transaction.UserTransaction.getStatus()可以取得事務(wù)當(dāng)前的狀態(tài)! 這樣的話,就比較簡單了。既然可以隨時(shí)取得事務(wù)的狀態(tài)編碼,而且又能清楚知道每個(gè)狀態(tài)碼的含義,就可以對(duì)事務(wù)進(jìn)行再次封裝了
我的解決辦法
package com.javer.test;
import javax.naming.Context; import javax.naming.InitialContext; import javax.transaction.Status; import javax.transaction.UserTransaction;
/** * 事務(wù)管理器,對(duì)事務(wù)再次進(jìn)行封裝 * <p>@author javer QQ:84831612</p> * @date 2005 */ public class TransactionManager {
private UserTransaction tx = null;
/** * 是否自己管理事務(wù)(true:自己提交、回滾事務(wù);false:當(dāng)前事務(wù)是嵌套事務(wù),自己不進(jìn)行事務(wù)管理) */ private boolean transactionBySelf = true;
private TransactionManager(){}
public static TransactionManager getInstance() throws Exception { Context ic = new InitialContext(); UserTransaction _tx = (UserTransaction) ic.lookup("java:comp/UserTransaction"); //resin服務(wù)器中取得UserTransaction
TransactionManager tm = new TransactionManager(); tm.tx = _tx; if(_tx.getStatus() != Status.STATUS_NO_TRANSACTION) tm.transactionBySelf = false;
return tm; }
public void beginTransaction() throws Exception { if (tx == null) return; if(tx.getStatus() != Status.STATUS_NO_TRANSACTION) transactionBySelf = false;
if (transactionBySelf) { tx.begin(); //System.out.println("TransactionManager:打開事務(wù)!"); }//else { //System.out.println("TransactionManager:已經(jīng)處于事務(wù)中了!所以沒有再次打開事務(wù)!"); //} }
public void commitTransaction() throws Exception { if (tx == null) return; if (transactionBySelf) { tx.commit(); //System.out.println("TransactionManager:提交事務(wù)!"); }// else { //System.out.println("TransactionManager:已經(jīng)處于事務(wù)中了!所以沒有提前提交事務(wù)!"); //} }
public void rollbackTransaction() throws Exception { if (tx == null) return; if (transactionBySelf) { tx.rollback(); //System.out.println("TransactionManager:回滾事務(wù)!"); }// else { //System.out.println("TransactionManager:已經(jīng)處于事務(wù)中了!所以沒有提前回滾事務(wù)!"); //} } }
調(diào)用示例
方法a void a() throws Exception { TransactionManager tm = TransactionManager.getInstance(); try{ tm.beginTransaction();
System.out.println("JaverTest:數(shù)據(jù)庫操作!");
b(); //調(diào)用方法b
tm.commitTransaction(); }catch(Exception e){ tm.rollbackTransaction(); throw e; } }
方法b void b() throws Exception { TransactionManager tm = TransactionManager.getInstance(); try{ tm.beginTransaction();
System.out.println("JaverTest:數(shù)據(jù)庫操作!");
tm.commitTransaction(); }catch(Exception e){ tm.rollbackTransaction(); throw e; } }
|