Jsf 托管bean内的回滚事务

Jsf 托管bean内的回滚事务,jsf,transactions,ejb,Jsf,Transactions,Ejb,我不想回滚EJB内部的事务,而是在JSF托管bean内部的事务。在EJB内部,我们可以使用SessionContext.setRollBackOnly(),但在托管bean中我可以使用什么 @Stateless @Local(AccountLocal.class) public class AccountBean implements AccountLocal { public void test1() throws CustomException(){ ... }

我不想回滚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 ?
      }      
    }    
}
编辑:如何确保如果
test1
test2
test3
中的一个回滚,其他的也会回滚

我测试了这段代码并
accountBean.test1()accountBean.test2(),代码>也会被验证回滚

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

 @SessionScoped
public class LoginBean implements Serializable{

   public void test(){

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

如果抛出未检查的异常,EJB容器会自动回滚事务(请注意,JPA的
PersistenceException
就是这样一个异常)。您的
CustomException
似乎是选中的异常。如果将其更改为extend
RuntimeException
,如下所示

public class CustomException extends RuntimeException {
    // ...
}
或者创建一个新的注释不是一个选项,那么您需要将类上的注释设置为
rollback
属性设置为
true

例如

请注意,具体问题与JSF无关。服务层和事务管理完全不属于JSF的职责范围。而是EJB的责任。在这个透视图中,JSF应该仅仅充当“视图”

另见:

    • 我在这里扮演魔鬼代言人的角色,因为BalusC的建议绝对正确,即您不应该让支持bean充当服务

      但是,纯粹作为一种技术练习,可以在支持bean中启动JTA事务,然后以编程方式控制启动和提交或回滚

      您可以通过@Resource注入UserTransaction来实现这一点。在调用EJB方法之前,在此实例上调用start,在最后一次调用之后调用commit或rollback


      同样,这是一个纯理论的回答。实际上,不要这样做,让支持bean调用一个EJB方法,如果需要的话调用其他EJB bean。

      My
      CustomException
      正在扩展
      Exception
      类,所以我的事务没有回滚。再次非常感谢BalusC,您非常善于教学:)是的,创建一个新的EJB类/方法,通过一个方法调用执行所有这些服务任务。您知道,默认情况下,事务基本上跨越一个EJB方法调用。JSF支持bean方法不应充当服务。它应该仅仅通过一个方法调用将模型委托给服务,而不是决定需要执行哪些“子服务”调用。请注意,EJB方法反过来可以完美地调用另一个EJB类/方法。是的,我知道,这是因为我没有立即理解为什么在JSF bean中调用EJB方法不这样做(就交易而言)。不这样做的唯一原因是“纯粹是理论上的答案”?还是有技术原因(例如,性能问题)?
      @ApplicationException(rollback=true)
      public class CustomException extends Exception {
          // ...
      }