EJBの(トランザクション)メソッドが別のEJBの別の(トランザクション)メソッドを呼び出し、2番目のメソッドで例外がスローされたが、最初のメソッドでキャッチされた場合、2番目のメソッドが戻ったときにトランザクションが自動的にロールバックされるようです。最初のものがそれを捕まえたとしても、これは本当ですか?どうすればそれを回避できますか?
シナリオは次のとおりです。
@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() }
}
RuntimeException
またはrollback
属性がtrue
に設定された@ApplicationException
アノテーションを持つ例外をスローした場合、トランザクションはロールバックされます。
@ApplicationException(rollback=true)
public class MyException extends Exception {
// ...
}
現在のトランザクションをロールバックします。
デフォルトでは、ApplicationExceptionはトランザクションをロールバックしません。
MethodBでトランザクションをロールバックしたくない場合は、ApplicationException
のロールバック動作を変更するか、トランザクションの共有を防ぐことができます。
後者は、methodBのTransactionAttribute
をRequiresNew
に変更することで実現できます。次に、methodAトランザクション(Tx1)が一時停止され、methodBが例外をスローしてトランザクション(Tx2)がロールバックされた場合でも、methodAでキャッチして、methodAトランザクション(Tx1)のロールバックを防ぐことができます。
はい、例外が実行時例外である場合、それは真実です。チェックされた例外は、トランザクションのロールバックを引き起こしません。
これを回避するには、methodB
のコードがランタイム例外をスローしないことを確認してください。ランタイム例外は通常、バグ、または作業の続行を許可しない状態を示します。