10.2. Seam 管理トランザクション
EJB セッション Bean は宣言型トランザクション管理を特長としています。 EJB コンテナは Bean が呼び出されると透過的にトランザクションを起動し、 呼出しが終了するとトランザクションも終了させることが可能です。 JSF アクションリスナーとして動作するセッション Bean メソッドを記述する場合、 そのアクションに関連するすべての作業を 1 つのトランザクションとして行うことができ、 アクションの処理が完全に終了したらコミットまたはロールバックされるようにできます。これは便利な機能であり、いくつかの Seam アプリケーションに必要なのはこれだけです。
ただしこの方法には問題が 1 つあります。1 つのセッション Bean への単一のメソッド呼び出しの 1 要求で、 Seam のアプリケーションは全データアクセスを行うわけではありません。
- リクエストがいくつかの疎結合コンポーネントによる処理を必要とし、それぞれのコンポーネントが Web 層から個別に呼び出される場合です。 Seam でリクエストごと Web 層から EJB コンポーネントへの呼び出しが複数あるのはよく見られることです。
- ビューのレンダリングに関連の遅延フェッチが必要な場合です。
要求ごとに存在するトランザクション数が多くなると、 使用しているアプリケーションが多くの同時要求を処理している間にそれだけ多くのアトミック性と独立性の問題に遭遇する可能性が高くなります。 書き込み動作はすべて同じトランザクション内で起こらなければならないからです。
Hibernate ユーザーはこの問題に対処するため open session in view パターンを開発しました。 Spring のようなフレームワークはトランザクションスコープの永続コンテキストを使用しているのでこれも重要です。 これによりフェッチされない関連がアクセスされると
LazyInitializationException が引き起こされました。
Open session in view は要求全体に広がる単一トランザクションとして通常は実装されます。 この実装で最も深刻な問題は、コミットするまでトランザクションが成功したかがわからない点です。 ただし、 トランザクションがコミットされるとビューは完全にレンダリングされ、 レンダリングされた応答はすでにクライアントを同期している可能性があります。 このため、 ユーザーにトランザクションが成功しなかったことを伝える手段がありません。
Seam はトランザクション独立性の問題と関連フェッチの問題を解決しながら、open session in view の主要な不備な点にも対処します。 変更点が 2 つあります。
- Seam はトランザクションではなく対話に対してスコープされる拡張永続コンテキストを使用します。
- Seam は要求ごとに 2 つのトランザクションを使用します。 1 番目はビュー復元フェーズの開始からアプリケーション起動フェーズの終わりまでに渡り、2 番目はレスポンス出力フェーズまでに渡ります (アプリケーションの中には、 最初のフェーズがこれより後のリクエスト値の適用フェーズの開始時に始まるものもあります)。
次項では、対話スコープの永続コンテキストの設定方法について説明していきますが、その前に Seam トランザクション管理を有効にします。 Seam トランザクション管理なしで対話スコープの永続コンテキストを使用することができます。また、Seam 管理永続コンテキストがなくても Seam トランザクション管理を利用すると便利です。ただし、 この 2 つの機能は併用する方が効果的です。
10.2.1. Seam 管理トランザクションを無効にする リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Seam トランザクション管理はデフォルトではすべての JSF 要求に有効ですが、
components.xml で無効にすることができます。
<core:init transaction-management-enabled="false"/> <transaction:no-transaction />
<core:init transaction-management-enabled="false"/>
<transaction:no-transaction />