web-dev-qa-db-ja.com

EJB:トランザクションのロールバックを回避する

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() }
}
18
Mr.Eddart

RuntimeExceptionまたはrollback属性がtrueに設定された@ApplicationExceptionアノテーションを持つ例外をスローした場合、トランザクションはロールバックされます。

@ApplicationException(rollback=true)
public class MyException extends Exception {
    // ...
}

現在のトランザクションをロールバックします。

デフォルトでは、ApplicationExceptionはトランザクションをロールバックしません。

MethodBでトランザクションをロールバックしたくない場合は、ApplicationExceptionのロールバック動作を変更するか、トランザクションの共有を防ぐことができます。

後者は、methodBのTransactionAttributeRequiresNewに変更することで実現できます。次に、methodAトランザクション(Tx1)が一時停止され、methodBが例外をスローしてトランザクション(Tx2)がロールバックされた場合でも、methodAでキャッチして、methodAトランザクション(Tx1)のロールバックを防ぐことができます。

23
Piotr Nowicki

はい、例外が実行時例外である場合、それは真実です。チェックされた例外は、トランザクションのロールバックを引き起こしません。

これを回避するには、methodBのコードがランタイム例外をスローしないことを確認してください。ランタイム例外は通常、バグ、または作業の続行を許可しない状態を示します。

9
JB Nizet