当EJB的(事务性)方法调用另一个EJB的另一个(事务性)方法,并且在第二个中抛出异常但在第一个中捕获异常时,似乎事务在第二个时自动回滚一个人回来,即使第一个人抓住它,这是真的吗?我怎么能避免它?
场景如下:
@Stateless
class ClassA {
@EJB
ClassB objectB;
methodA() {
try {
objectB.methodB();
}
catch(Exception e) {
//Here the transaction started in this method is
//automatically rolled back. Is this avoidable?
}
}
}
@Stateless
class ClassB {
methodB() throws Exception { throw new Exception() }
}
答案 0 :(得分:21)
如果您抛出RuntimeException
或任何具有@ApplicationException
注释且rollback
属性设置为true
的异常,则会回滚事务,因此:
@ApplicationException(rollback=true)
public class MyException extends Exception {
// ...
}
将回滚当前事务。
默认情况下,ApplicationException不会回滚您的事务。
如果您不希望methodB回滚您的事务,您可以更改ApplicationException
的回滚行为或阻止事务共享。
后者可以通过将methodB的TransactionAttribute
更改为RequiresNew
来实现。然后methodA transaction(Tx1)将是suspendend,如果methodB抛出一个导致其事务回滚(Tx2)的异常,你仍然可以在methodA中捕获它并阻止回滚methodA事务(Tx1)。
答案 1 :(得分:9)
是的,如果异常是运行时异常,那是真的。已检查的异常不会导致事务回滚。
要避免它,只需确保methodB
中的代码不会抛出任何运行时异常。运行时异常通常表示错误,或者不允许继续工作的状态。