在托管bean中回滚事务

时间:2012-12-23 16:20:10

标签: jsf transactions ejb

我想回滚事务不是在EJB内部而是在JSF托管bean内部。在EJB内部,我们可以使用SessionContext.setRollBackOnly(),但我可以在托管bean中使用什么?

@Stateless
@Local(AccountLocal.class)
public class AccountBean implements AccountLocal {

   public void test1() throws CustomException(){
      ...
   } 

   public void test2() throws CustomException(){
      ...
      throw new CustomException();
   }   

   public void test3() throws CustomException(){
      ...
   }

   public void all() throws CustomException(){
       test1();
       test2();
       test3();
   } 

}

在我的托管bean中:

@SessionScoped
public class LoginBean implements Serializable{

   public void test(){

      try{
         accountBean.test1();
         accountBean.test2();
         accountBean.test3();
      }catch(CustomException e){
         // WHAT HERE TO ROLLBACK TRANSACTION ?
      }      
    }    
}

编辑:如果其中一个test1test2test3回滚,其他人也会回滚,我该如何确保?

我测试了此代码,即使accountBean.test1();回滚,也会验证accountBean.test2();

解决方案是否只能将这3个方法嵌套在一个EJB方法中?

 @SessionScoped
public class LoginBean implements Serializable{

   public void test(){

      try{
         accountBean.all();
      }catch(CustomException e){
        ...
      }      
    }    
}

2 个答案:

答案 0 :(得分:5)

如果抛出未经检查的异常,则EJB容器会自动回滚事务(请注意JPA的PersistenceException就是这样)。您的CustomException似乎是经过检查的例外情况。如果将其更改为扩展RuntimeException,如下所示

public class CustomException extends RuntimeException {
    // ...
}

或创建一个新选项不是一个选项,那么您需要在rollback属性设置为true的类中设置@ApplicationException注释。

E.g。

@ApplicationException(rollback=true)
public class CustomException extends Exception {
    // ...
}

请注意,具体问题与JSF无关。服务层和管理事务完全不在JSF的责任范围内。这是EJB的责任。从这个角度来看,JSF应该仅仅充当“观点”。

另见:

答案 1 :(得分:1)

我在这里扮演魔鬼的拥护者,因为BalusC的建议是你不应该让你的支持豆子充当服务是绝对正确的。

但是,纯粹作为技术上的例外,它可以在辅助bean中启动JTA事务,然后以编程方式控制启动,提交或回滚。

您可以通过@Resource注入UserTransaction来完成此操作。在调用EJB方法之前,请在此实例上调用start,并在最后一次调用之后调用commit或rollback。

同样,这是纯理论答案。在实践中,不要这样做,让支持bean调用1个EJB方法,如果需要,可以调用其他EJB bean。