EJB3ステートレスセッションBeanでCMTを使用しています。また、注釈「@ApplicationException(rollback = true)」を持つ独自の例外を作成しました。
トランザクションをロールバックする場合、「context.setRollbackOnly()」を使用する必要がありますか?
Beanのパブリックメソッド内で例外をスローするだけで、トランザクションをロールバックできますか?
もしそうなら(Q#2の答えはイエスです)、メソッド内で例外を宣言することでメソッドから例外をスローする必要がありますか、それともメソッド内で例外をスローして同じメソッド内で処理するだけで十分ですか?自体? (例外を次のレベルに伝搬したくありません。例外をロールバックしたいだけです。)
前もって感謝します。 ;)
まず、例外のロールバックはありません。トランザクションのロールバックです。
@ApplicationException(rollback=true)
で例外をスローする場合、トランザクションを手動でロールバックする必要はありません。 Context.setRollbackOnly()
は、例外がない場合もコンテナにトランザクションを強制的にロールバックさせます。@ApplicationException(rollback=true)
が必要です。例外がRuntimeException
であり、例外がキャッチされない場合、コンテナはトランザクションを強制的にロールバックします。ただし、この場合、コンテナはEJBインスタンスを破棄します。RuntimeException
をスローすると、トランザクションは自動的にロールバックされます。コード内でチェック例外をキャッチした場合、setRollbackOnly
を使用してトランザクションをロールバックする必要があります。詳細については、無料の本 Mastering EJB をご覧ください。ロールバックシナリオを非常によく説明し、 ダウンロード の場合は無料です。
スローされたロールバックが「上位層」に伝播されるようにアノテーションで宣言されたチェック済み例外を防ぐ方法の質問は、ここではまだ回答されていません。
これには、スローされた例外を飲み込む問題のEJBのラッパーが必要になると思います。 (言い換えると、カスタム例外はメソッド境界に対してスローされなければならず(したがって、メソッド内でキャッチおよび処理されず)、トランザクション効果を得るために伝播されなければならず、またEJBインスタンスの破壊を引き起こすと考えられます)