| JBoss EJB 3.0と拡張機能
アプリケーショントランザクション
はじめに
| 標準的なJTAのトランザクションはスレッドベースです。トランザクションはスレッドの最後にコミットかロールバックしなければなりません。スレッドの最後にトランザクションはコミットされ、データの変更はデータベースへフラッシュされ、`EntityManager`の永続コンテキストは破棄されます。Webアプリケーションにとっては、これはいくつかの問題になります。Webアプリケーションでは各Webリクエストは独自のスレッドで動作しますが、複数のリクエストが論理的にひとつのトランザクションセッションに結び付けられることがあるからです。例としてショッピングカートのアプリケーションを考えましょう。ユーザは商品を選び、クレジットカード情報を入力し、発送先を入力し、最終的な価格を確認し、最後に全体のトランザクションを終了するために、複数のWebページを移動する必要があります。各ページでのサブミットはサーバ上の別々のスレッドで処理されますが、注文がデータベースへコミットされるのは最後のページの後のみであるべきです。これをJTAのトランザクションマネージャで実装するのは困難です。 EJB 3.0では、ステートフルセッションBeanでのマルチスレッドトランザクション (すなわちアプリケーショントランザクション)をサポートするため`EntityManager`を「長期生存させる」オプションがあります。長期生存`EntityManager`はホストとなるステートフルセッションBeanのインスタンスが破棄される (すなわち永続コンテキストが破棄される)までコミットしません。このトレイルでは、アプリケーショントランザクションの使い方を取り上げます。
サンプルアプリケーション
| このトレイルのサンプルアプリケーションは、前のトレイルで見た投資計算プログラムのための「為替変換レート更新」アプリケーションの単純なバリエーションです。新しい為替変換レートをサブミットすると、アプリケーションはエンティティBeanオブジェクトのすべての計算レコードを更新しますが、まだ変更をデータベースへフラッシュしません。そしてアプリケーションは次のページを表示し、これらのレコードのタイムスタンプを更新するかどうかを尋ねます。「はい」を選択すれば、Beanオブジェクトのタイムスタンプ属性も更新され、すべての変更がひとつのバッチ処理でデータベースにフラッシュされます。
拡張`EntityManager`
| アプリケーショントランザクションを使うには、`@PersistenceContext`インジェクションアノテーションの`type`属性に`PersistenceContextType.EXTENDED`を指定するだけです。それはコンテナに、このBeanの`EntityManager`オブジェクトがスレッドまたはメソッド呼び出しの最後でその永続コンテキスト (すなわち`EntityManager`が管理するBean)を維持するよう、伝えます。
    @Stateful
    public class ApptransCalculator implements Calculator, Serializable {

      @PersistenceContext(
          type=PersistenceContextType.EXTENDED
      )
      protected EntityManager em;

      // ... ...

    }
トランザクションをコミットする
| 説明したように、`EntityManager`はステートフルセッションBeanが破棄されたときのみデータベースを更新します。`@Remove`をタグ付けしたメソッドを呼べばステートフルセッションBeanを破棄できることを思い出してください。データベースが同期化されることを確実にするため、`@Remove`メソッド内で`EntityManager.flush()`メソッドを呼ぶようにもしています。
    @Stateful
    public class ApptransCalculator implements Calculator, Serializable {

      // ... ...

      @TransactionAttribute(TransactionAttributeType.REQUIRED)
      public void updateExchangeRate (double newrate) {
        // ... ...
      }

      @TransactionAttribute(TransactionAttributeType.REQUIRED)
      public void updateTimestamp () {
        // ... ...
      }

      @Remove
      public void checkout() throws Exception {
        em.flush ()
      }

    }
ソースコード参照
| サーバ Calculator.java: CalculatorBeanセッションBeanのローカルインターフェース ApptransCalculator.java: 拡張したアプリケーショントランザクション対応のステートフルセッションBean クライアント calculator.jsp: 更新トランザクションの第一段階を実行するクライアントJSP check.jsp: 更新トランザクションの第二段階を実行するクライアントJSP
まとめ
| このトレイルでは、ショッピングカートアプリケーションのような複数ページアプリケーションのトランザクションのために、長期生存EntityManagerオブジェクトを使う方法を学びました。次のトレイルでは、管理対象オブジェクトとメソッドのための別タイプのコンテナサービスであるセキュリティサービスについて論じます。