TX その8 CMTトランザクションタイプ NotSupported, Required・・・の処理のされ方

蛇足.

CMTを使う場合に"ejb-jar.xml"で指定するトランザクションタイプとして"NotSupported", "Required"等々のキーワードがあると思う.

これらのキーワードは,EJBへの毎回の呼び出し時にインターセプトの1つとして呼び出されるTxInterceptorCMTクラスのrunWithTransactionsメソッドで処理される.switch-case構文と定数を使って場合わけされて処理される.

例えばトランザクションタイプが"NotSupported"の場合,runWithTransactionsメソッドの中では,

  1. 呼び出し元から引き継いだトランザクションコンテキストを一度退避させて
  2. トランザクションコンテキストを空にして
  3. 次のインタセプタを呼び出す.
  4. インタセプタからインタセプタへの呼び出し連続的に行われて
  5. StatelessSessionInstanceInterceptor(SLSBの場合)まで行くと実際にEJBのメソッドが呼び出されて
  6. もし例外がスローされると一度catchして
  7. EJB仕様で言うところのアプリケーション例外だったら再スローし
  8. システム例外だったら
  9. この場合はトランザクションコンテキストが空なので何もせずに
  10. 退避させておいた呼び出し元のトランザクションコンテキストを元に戻した上で
  11. やはり単純に再スローする
  12. 例外がスローされなかった場合には特に無し

という流れになる.

トランザクションタイプが"Required"の場合は,

  1. 呼び出し元から引き継いだトランザクションコンテキストを一度退避させて
  2. もしそれが実は空だったら新しいトランザクションコンテキストを生成して開始させて
  3. 空でなかったらトランザクションコンテキスト再開させて(中断状態で呼ばれるので)
  4. 次のインタセプタを呼び出す.
  5. インタセプタからインタセプタへの呼び出し連続的に行われて
  6. StatelessSessionInstanceInterceptor(SLSBの場合)まで行くと実際にEJBのメソッドが呼び出されて
  7. もし例外がスローされると一度catchして
  8. EJB仕様で言うところのアプリケーション例外だったら再スローし
  9. システム例外だったら
  10. この場合はトランザクションコンテキストに対してsetRollbackOnlyを行い
  11. 呼び出し元にトランザクションコンテキストが存在していなければ単に再スローする
  12. 呼び出し元にトランザクションコンテキストが存在していれば
  13. setRollbackOnlyを行ったことを通知するための例外をスローする
  14. 例外がスローされなかった場合には
  15. 新しいトランザクションコンテキストを生成/開始していたのであれば終了させ
  16. 引き継いだトランザクションコンテキストを使っていたのであれば中断させる

(退避させておいた呼び出し元のトランザクションコンテキストを元に戻すのは必ず行われる)

こんな感じだ.やばい.楽しい〜.

そういえばトランザクションの状態管理って以前開発に関わったフレームワークでもやってたな.J2EEサーバとはいえJavaアプリケーションなわけで,書き方とか,大きな違いはないんだよね.



蛇足2

JBossのCMTはExceptionがスローされた場合,デフォルトで5回までリトライします.この際,Exceptionの原因がリトライ不可能なデッドロック(可能な場合あり)であればリトライせずに再スローします.リトライまでの時間間隔はランダム要素込みで1秒くらいかも.

へぇ〜〜〜,驚いた.ソースを読むと知らないことばかりですなあ.