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