2009年12月6日日曜日

コンテナ管理トランザクションであそぶ - (9/10) -

検証する

Webブラウザから検証ページ(『http://localhost:8080/webtest-client/』)にアクセスして動作を確認します。
検証用Webアプリの説明

  • ラジオボタンでロールバックするポイント、またはコミットを選択して 『access』 ボタンを押します。
    (メソッド処理の最後に例外が発生してロールバックします。)
  • セッションIDとセッションIDが登録されたクラスとメソッドの呼出しツリーが一覧に表示されます。
検証する
  1. ラジオボタンでNo.3の Rollback を選択して 『access』 ボタンを押します。

    No.2の処理(ActionImplクラスのdecorateInsert()メソッド)は
    TransactionAttributeType.REQUIRES_NEWが指定されているので
    No.3の処理(ActionImplクラスのinsert()メソッド)で例外が発生しても
    No.2の処理は登録されるはずなのですが登録されていません。
    これはNo.2の処理がActionImplクラスのregist()メソッドから呼出されているため
    regist()メソッドが呼出された段階でActionImplクラスのEntityManagerにトランザクションが設定されるようです。
    この時のトランザクションはregist()メソッドで指定されたTransactionAttributeType.REQUIRED(デフォルト)になり
    regist()メソッドの処理が終了するまでの間、このクラスのメソッドはTransactionAttributeTypeの指定に関わらず
    同一のトランザクションとして処理されるようです。

  2. ラジオボタンでNo.6の Rollback を選択して 『access』 ボタンを押します。

    No.6の処理(SubActionImplクラスのinsert()メソッド)はActionImplクラスのregist()メソッドで設定された
    トランザクションの参加することになるようで、No.6の処理で例外が発生すると
    ActionImplクラスのメソッドでの処理 (No.2~4)も一緒にロールバックされるようです。
    No.5の処理(SubActionImplクラスのdecorateInsert()メソッド)は
    TransactionAttributeType.REQUIRES_NEWが指定されているので、
    このメソッドが呼出された段階で SubActionImplクラスのEntityManagerに
    別トランザクションが設定されメソッド処理の終了時にコミットされているようです。
    そのためNo.5の処理はロールバックされず登録されています。

  3. ラジオボタンでNo.8の Rollback を選択して 『access』 ボタンを押します。

    No.8の処理(SubActionImplクラスのrequiresNewInsert()メソッド)で発生した例外は
    ActionImplクラスのregist()メソッドで catch しているので
    他のメソッドの処理は ロールバックされず登録されるようです。

  4. ラジオボタンでNo.1の Rollback を選択して 『access』 ボタンを押します。

    No.7の処理(SubActionImplクラスのdecorateInser()メソッド)は
    TransactionAttributeType.REQUIRES_NEWが 指定されているのですが
    No.6の処理(SubActionImplクラスのinsert()メソッド)から呼出されているため
    No.6の処理で設定されたトランザクション(ActionImplクラスのregist()メソッドで設定されたトランザクション)に
    参加することになり、No.1の処理で例外が発生するとActionImplクラスのメソッドでの処理 (No.2~4)と
    SunActionImplクラスのNo.6、No.7の処理はロールバックされるようです。
    No.5の処理(SubActionImplクラスのdecorateInsert()メソッド)は
    別トランザクションで処理されているので ロールバックせずに登録されるようです。
    No.8の処理(SubActionImplクラスのrequiresNewInsert()メソッド)は
    TransactionAttributeType.REQUIRES_NEWが 指定されたメソッドなので
    別トランザクションで処理されることからNo.8の処理、そしてこの処理から呼出される
    No.6、No.7の処理は ロールバックせずに登録されるようです。

  5. ラジオボタンで Commit を選択して 『access』 ボタンを押します。

    すべての登録処理が実行されます。

結果考察
  • Session Beanのフィールドに置かれたEntityManagerは Session Beanのインスタンスを通して
    最初に呼出されたメソッドの TransactionAttributeTypeに従ってトランザクションを開始するようだ。
    そしてそのメソッドの処理が終了するまでそのクラスのメソッドはTransactionAttributeTypeの指定に関わらず
    同一のトランザクションとして処理されるようだ。
  • 同じクラスの同じメソッドであっても呼出される条件によって参加するトランザクションが変わるようだ。
  • 1つのEntityManagerのインスタンスは1つのトランザクションを管理するようだ。