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