在托管bean中回滚事务

Oli*_* J. 3 jsf ejb transactions

我想回滚事务不是在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();
   } 

}
Run Code Online (Sandbox Code Playgroud)

在我的托管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 ?
      }      
    }    
}
Run Code Online (Sandbox Code Playgroud)

编辑:我怎么能保证的是,如果一个test1,test2test3回滚,其他人将回滚呢?

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

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

 @SessionScoped
public class LoginBean implements Serializable{

   public void test(){

      try{
         accountBean.all();
      }catch(CustomException e){
        ...
      }      
    }    
}
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 5

如果抛出未经检查的异常,则EJB容器会自动回滚事务(请注意,JPA PersistenceException就是这样).你CustomException似乎是一个经过检查的例外.如果改变它扩展RuntimeException如下

public class CustomException extends RuntimeException {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

或者创建一个新选项不是一个选项,那么您需要@ApplicationExceptionrollback属性设置为的类上设置注释true.

例如

@ApplicationException(rollback=true)
public class CustomException extends Exception {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

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

也可以看看:

  • 是的,创建一个新的EJB类/方法,通过单个方法调用执行所有这些服务任务.您知道,事务默认基本上跨越一个EJB方法调用.JSF支持bean方法不应该充当服务.它应该仅通过单个方法调用将模型委托给服务,而不是决定需要执行哪些"子服务"调用. (2认同)