今日、EJBで予期しない動作を発見しました。デフォルトのトランザクション属性(REQUIRED
)を持つMDBと、トランザクション属性がに設定されたSLSBがありますREQUIRES_NEW
。私のMDBはSLSBを呼び出し、SLSBがスローできる例外をキャッチします。SLSBで本当に悪いことが発生し、のサブクラスRuntimeException
がスローされたとき。次に、SLSB用に作成された新しいトランザクションがロールバックのマークになりました。私の観点からは、これは正しい動作です。次に、MDBはこの例外をキャッチし、再スローして何らかのアクション(たとえば、ログにメッセージを書き込む)を実行します。しかし、MDBトランザクションもどういうわけかロールバックのマークが付けられたので、私には奇妙に思えます。この動作は正しいですか?
より正確に言うと、実際のコードに似たコードを記述して、この動作を生成することができます。
@MessageDriven
public class A{
@EJB
private B b;
@Overried
public void onMessage(Message msg){
...
try{
b.process(msg);
} catch (Throwable t){
logger.error("Something gone wrong",t);
}
...
}
そして、SLSBは次のようになります。
@EJB
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class B{
public void process(Message msg){
...
}
}
問題のあるタスクフローは次のようになります。
- メッセージ駆動型Bean
onMessage(Message)
が呼び出されました。 - メッセージ駆動型Beanは、いくつかのアクションを正常に実行してから、メソッドを呼び出し
B.process(Message)
ます。 - 何か悪いことが
B
起こり、RuntimeException
投げられました。 RuntimeException
ラップされEJBException
、メッセージ駆動型Beanによって正常にキャッチされました。- メッセージ駆動型Bean
onMessage(Message)
メソッドは完全に実行されましたが、そのトランザクションはロールバックのマークが付けられました。
誰かがこの行動を説明できますか?前もって感謝します。