成功解决事务嵌套

JTA事务的嵌套

  由于前两篇帖子都是关于事务的讨论 (J2EE中的事务处理<script language="javascript" type="text/javascript"> document.title="朝花夕拾 之 J2EE中的事务处理 - "+document.title </script> 、 事务服务浅析),没有讨论到事务嵌套时的解决办法,这两天一直在琢磨,如何才能高效、灵活的解决事务的嵌套问题呢?
  既然web容器可以判断当前方法是否处在事务中(JTA事务中提交java.sql.Connection.commit()会报错),那么它是如何判断的呢?带着这个疑问,追查了一下resin容器源码的事务部分,发现了一个类:javax.transaction.Status,用来标明事务状态代码,而javax.transaction.UserTransaction.getStatus()可以取得事务当前的状态!
  这样的话,就比较简单了。既然可以随时取得事务的状态编码,而且又能清楚知道每个状态码的含义,就可以对事务进行再次封装了

我的解决办法

package com.javer.test;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.transaction.Status;
import javax.transaction.UserTransaction;

/**
 
* 事务管理器,对事务再次进行封装
 
* <p>@author javer QQ:84831612</p>
 
* @date 2005
 
*/
public class TransactionManager {

 
private UserTransaction tx = null;

 
/**
  
* 是否自己管理事务(true:自己提交、回滚事务;false:当前事务是嵌套事务,自己不进行事务管理)
  
*/
 
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服务器中取得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:打开事务!");
   
}//else {
     
//System.out.println("TransactionManager:已经处于事务中了!所以没有再次打开事务!");
    //
}
 
}

 
public void commitTransaction() throws Exception {
   
if (tx == null)
     
return;
   
if (transactionBySelf) {
      tx.commit();
     
//System.out.println("TransactionManager:提交事务!");
   
}// else {
     
//System.out.println("TransactionManager:已经处于事务中了!所以没有提前提交事务!");
    //
}
 
}

 
public void rollbackTransaction() throws Exception {
   
if (tx == null)
     
return;
   
if (transactionBySelf) {
      tx.rollback();
     
//System.out.println("TransactionManager:回滚事务!");
   
}// else {
     
//System.out.println("TransactionManager:已经处于事务中了!所以没有提前回滚事务!");
    //
}
 
}
}

调用示例

方法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;
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值