EJB 3.1事务回滚不起作用

时间:2014-02-28 08:48:29

标签: transactions ejb-3.1 rollback

我有以下情况:

我有一个带有两个方法A()B()的无状态ejb。方法B()执行对方法A()的调用,该方法执行INSERT操作。 现在,如果A()抛出一个applicationException(我已用@javax.ejb.ApplicationException(rollback=true)注释)并且我在方法B()的catch块中捕获此异常,则不会回滚我的事务,因此执行INSERT:

  

public void A()抛出ApplicationException {

.....//some logic here

doInsert(); //entity layer method that perform the insert operation

throw new ApplicationException(); // this is only for test
     

}

这是方法B():

  

public void B(){

     

尝试{

   A(); //this method is called n time in a loop but it doesn't matter
     

} catch(ApplicationException e){

     

e.printStackTrace();

     

}

这是applicationException:

  

@ javax.ejb.ApplicationException(回滚=真)   公共类ApplicationException扩展了Exception {

public ApplicationException() {

   super();

}
     

}

显然,如果我删除方法B()中的catch块,则不会发生此行为。 现在,我想知道是否有办法回滚我的事务,即使我在方法B()中捕获异常。 Thankss !!!!

2 个答案:

答案 0 :(得分:1)

根据EJB 3.1规范的第14.2.1节:

  

被检查异常的应用程序异常可以定义为   通过被列入方法的抛出条款   bean的业务接口,无接口视图,home接口,组件   接口和Web服务端点。一个应用程序异常   未经检查的异常被定义为应用程序异常   使用ApplicationException元数据注释来注释它,或者   用部署描述符在部署描述符中表示它   application-exception元素。

您的异常类扩展了Exception,因此它是一个已检查的异常,因此忽略@ApplicationException注释。如果你想在抛出异常时回滚异常,你应该在捕获A中的异常后使用EJBContext.setRollbackOnly(它也可以在抛出异常之前完成,但是从catch块执行它可能是一个更好的样式,因为它强调“处理”例外)。或者,您可以更改例外以扩展RuntimeException,但您可能不希望这样做,具体取决于您对未经检查的例外的看法。

答案 1 :(得分:1)

为了使代码工作,B()必须通过查找过程来获取ejb的另一个实例,并在该实例上调用A()。这样容器就有机会“看到”异常A()抛出。