10 EJBアプリケーションのトランザクション
始める前に
WebLogic Server EJBアプリケーションでトランザクションを処理する前に、EJBアプリケーションによって提供されているサンプル・コード・フラグメントを使用してEJBトランザクションの概念およびその実装を理解しておく必要があります。
開始する前に、「トランザクションについて」(特に次のトピック)を読んでください。
ここでは、Enterprise JavaBeansでのトランザクションのOracle WebLogic Server実装について説明します。ここで説明する情報は、「Enterprise JavaBeans仕様2.1」を補足するものです。
ノート:
この章を読み進める前に、EJB仕様2.1のドキュメントの内容、特にSupport for Transactionsの章に記載されている概念やデータをよく理解しておく必要があります。
WebLogic ServerアプリケーションでのEnterprise JavaBeansの実装は、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』を参照してください。
ガイドライン
WebLogic Server向けのEJBアプリケーションでトランザクションを実装するガイドラインを理解します。
以下のガイドラインは、WebLogic Server向けのEJBアプリケーションでトランザクションを実装するときに適用されます。
-
EJB仕様では、フラット・トランザクションのみがサポートされています。トランザクションをネストすることはできません。
-
EJB仕様では、複数のリソース(データベースなど)にまたがる分散トランザクションと、EJB CMP 2.1およびEJB CMP 1.1に対応した2フェーズ・コミット・プロトコルがサポートされています。
-
標準的なプログラミング手法を使用してトランザクション処理を最適化します。たとえば、トランザクションの境界を適切に設定すると、トランザクションの処理が速くなります。
-
EJBが実行されているWebLogic Serverインスタンス上の、ローカルTxDataSourceからデータベース接続を使用します。リモートWebLogic Serverインスタンス上のTxDataSourceからは接続を使用しないでください。
-
トランザクション対応のEJBアプリケーションでパフォーマンスを最大限に引き出すために、必ずEJBキャッシュを調整します。「Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発」を参照してください。
WebLogic Serverトランザクション・サービスのガイドラインについては、「機能と制限」を参照してください。
トランザクション属性
コンテナ管理およびBean管理のトランザクションのトランザクション属性を学習します。
EJBのトランザクション属性について
トランザクション属性では、トランザクションがEJBアプリケーションでどのように管理されるのかが指定されます。各EJBについて、トランザクション属性により、トランザクションの境界がWebLogic Server EJBコンテナによって設定されるのか(コンテナ管理のトランザクション)、またはEJB自体によって設定されるのか(Bean管理のトランザクション)が指定されます。EJBがコンテナ管理とBean管理のどちらであるのかは、デプロイメント記述子のtransaction-type
要素の設定で決まります。transaction-type
要素の詳細は、EJB仕様2.1の第16章「Support for Transactions」と第21章「Deployment Descriptor」を参照してください。
概して、Bean管理のトランザクションよりもコンテナ管理のトランザクションの方がよく使用されます。なぜなら、その方がアプリケーションのコードがシンプルになるからです。たとえば、コンテナ管理のトランザクションでは、トランザクションを明示的に開始する必要がありません。
WebLogic Serverでは、EJB仕様2.1のセクション16.4で定義されているメソッド・レベルのトランザクション属性が完全にサポートされています。
コンテナ管理のトランザクションのトランザクション属性
コンテナ管理のトランザクションの場合、トランザクション属性はデプロイメント記述子のcontainer-transaction
要素で指定します。コンテナ管理のトランザクションには、すべてのエンティティBeanと、transaction-type
がContainer
に設定されているステートフルまたはステートレスのセッションBeanが含まれます。これらの要素の詳細は、 『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』を参照してください。
EJBとそのビジネス・メソッドに対して指定できるトランザクション属性は以下のとおりです。
-
NotSupported
-
Supports
-
Required
-
RequiresNew
-
Mandatory
-
Never
trans-attribute
の設定に対するWebLogic Server EJBコンテナの反応については、EJB仕様2.1のセクション17.6.2 (http://www.oracle.com/technetwork/java/javaee/ejb/index.html
)を参照してください。
デプロイメント記述子でタイムアウト値が定義されていない場合は、WebLogic Server EJBコンテナによって自動的にトランザクションのタイムアウトが設定されます。コンテナではTimeout Seconds
構成パラメータの値が使用されます。デフォルトのtimeout値は30秒です。
コンテナ管理のトランザクションを使用するEJBの場合、EJBはjavax.transaction.UserTransaction
インタフェースにアクセスすることができず、また、開始と終了のトランザクション・コンテキストが一致していなければなりません。さらに、コンテナ管理のトランザクションを使用するEJBでは、javax.ejb.EJBContext
インタフェースのsetRollbackOnly
メソッドとgetRollbackOnly
メソッドのサポートが制限されています(EJB仕様2.1のセクション16.4.4.2と16.4.4.3で規定されている規則によって呼出しが制限されます)。
Bean管理のトランザクションのトランザクション属性
Bean管理のトランザクションの場合は、Beanがjavax.transaction.UserTransaction
インタフェースのメソッドを使用してトランザクションの境界設定を指定します。Bean管理のトランザクションには、transaction-type
がBean
に設定されているステートフルまたはステートレスのセッションBeanが含まれます。エンティティBeanでは、Bean管理のトランザクションは使用できません。
ステートレス・セッションBeanの場合は、開始と終了のトランザクション・コンテキストが一致していなければなりません。ステートフル・セッションBeanの場合は、開始と終了のトランザクション・コンテキストが必ずしも一致している必要はありません。一致していない場合は、WebLogic Server EJBコンテナによってBeanと未終了のトランザクションとの関連付けが維持されます。
Bean管理のトランザクションを使用するセッションBeanでは、javax.ejb.EJBContext
インタフェースのsetRollbackOnly
メソッドとgetRollbackOnly
メソッドは使用できません。
トランザクションへの参加
用語「トランザクションへの参加」の使用方法を理解します。これは、一般的にBeanがコンテナ管理トランザクションまたはBean管理トランザクションでBeanが起動されるときに使用されます。
EJB仕様2.1で使用される「トランザクションに参加する」という表現は、Beanが次のいずれかの条件を満たしていると解釈します。
-
Beanがトランザクション・コンテキスト(コンテナ管理のトランザクション)で呼び出されます。
-
Beanが、クライアントによって呼び出されたBeanメソッドの中でUserTransaction APIを使用してトランザクションを開始し(Bean管理のトランザクション)、かつ、クライアントによって呼び出された対応するBeanメソッドの終了時にそのトランザクションをサスペンドまたは終了しない。
トランザクション・セマンティクス
コンテナ管理およびBean管理のトランザクションのトランザクション・セマンティクスを学習します。
EJB仕様2.1では、EJBの種類(エンティティBean、ステートレス・セッションBean、またはステートフル・セッションBean)とトランザクションの種類(コンテナ管理またはBean管理)に基づいてトランザクション処理の動作を決定するセマンティクスが規定されています。それらのセマンティクスでは、メソッドが呼び出されるときのトランザクション・コンテキストが規定されており、また、EJBがjavax.transaction.UserTransaction
インタフェースのメソッドにアクセスできるかどうかが定義されています。EJBアプリケーションは、それらのセマンティクスに注意して設計する必要があります。
コンテナ管理のトランザクションのトランザクション・セマンティクス
コンテナ管理のトランザクションの場合、トランザクション・セマンティクスはBeanの種類によって異なります。
ステートフル・セッションBeanのトランザクション・セマンティクス
表10-1に、コンテナ管理のトランザクションにおける、ステートフル・セッションBeanのためのトランザクション・セマンティクスを示します。
表10-1 コンテナ管理のトランザクションのステートフル・セッションBeanのトランザクション・セマンティクス
メソッド | メソッドが起動された時点でのトランザクション・コンテキスト | UserTransactionメソッドにアクセスできるか |
---|---|---|
|
指定なし |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
いいえ |
ビジネス・メソッド |
トランザクション属性によって「はい」または「いいえ」 |
いいえ |
|
はい |
いいえ |
|
はい |
いいえ |
|
いいえ |
いいえ |
ステートレス・セッションBeanのトランザクション・セマンティクス
表10-2は、コンテナ管理のトランザクションのステートレス・セッションBeanのトランザクション・セマンティクスを示したものです。
表10-2 コンテナ管理のトランザクションのステートレス・セッションBeanのトランザクション・セマンティクス
メソッド | メソッドが起動された時点でのトランザクション・コンテキスト | UserTransactionメソッドにアクセスできるか |
---|---|---|
|
指定なし |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
いいえ |
ビジネス・メソッド |
トランザクション属性によって「はい」または「いいえ」 |
いいえ |
エンティティBeanのトランザクション・セマンティクス
表10-3は、コンテナ管理のトランザクションのエンティティBeanのトランザクション・セマンティクスを示したものです。
表10-3 コンテナ管理のトランザクションのエンティティBeanのトランザクション・セマンティクス
メソッド | メソッドが起動された時点でのトランザクション・コンテキスト | UserTransactionメソッドにアクセスできるか |
---|---|---|
コンストラクタ |
指定なし |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
いいえ |
|
対応するcreateのトランザクション属性で決まります |
いいえ |
|
対応するcreateのトランザクション属性で決まります |
いいえ |
|
対応するremoveのトランザクション属性で決まります |
いいえ |
|
対応するfindのトランザクション属性で決まります |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
いいえ |
|
|
いいえ |
|
|
いいえ |
ビジネス・メソッド |
トランザクション属性によって「はい」または「いいえ」 |
いいえ |
Bean管理のトランザクションのトランザクション・セマンティクス
Bean管理のトランザクションの場合、トランザクション・セマンティクスはステートフルとステートレスのセッションBeanで異なります。エンティティBeanでは、Bean管理のトランザクションは利用できません。
ステートフル・セッションBeanのトランザクション・セマンティクス
表10-4は、Bean管理のトランザクションのステートフル・セッションBeanのトランザクション・セマンティクスを示したものです。
表10-4 Bean管理のトランザクションのステートフル・セッションBeanのトランザクション・セマンティクス
メソッド | メソッドが起動された時点でのトランザクション・コンテキスト | UserTransactionメソッドにアクセスできるか |
---|---|---|
コンストラクタ |
指定なし |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
はい |
|
指定なし |
はい |
|
指定なし |
はい |
|
指定なし |
はい |
|
通常は、Beanでの直前のメソッド実行がトランザクション・コンテキストの中で終了していないかぎり、「いいえ」 |
はい |
|
適用なし |
適用なし |
|
適用なし |
適用なし |
|
適用なし |
適用なし |
ステートレス・セッションBeanのトランザクション・セマンティクス
表10-5は、Bean管理のトランザクションのステートレス・セッションBeanのトランザクション・セマンティクスを示したものです。
表10-5 Bean管理のトランザクションのステートレス・セッションBeanのトランザクション・セマンティクス
メソッド | メソッドが起動された時点でのトランザクション・コンテキスト | UserTransactionメソッドにアクセスできるか |
---|---|---|
コンストラクタ |
指定なし |
いいえ |
|
指定なし |
いいえ |
|
指定なし |
はい |
|
指定なし |
はい |
ビジネス・メソッド |
いいえ |
はい |
セッションの同期
コンテナ管理のトランザクションを使用するステートフル・セッションBeanでは、javax.ejb.SessionSynchronization
インタフェースを実装してトランザクション同期通知を提供できます。
その場合、ステートフル・セッションBeanのすべてのメソッドでは、REQUIRES_NEW
、MANDATORY
、またはREQUIRED
のいずれかのトランザクション属性をサポートしなければなりません。javax.ejb.SessionSynchronization
インタフェースの詳細は、EJB仕様2.1のセクション6.5.3を参照してください。
トランザクション時の同期
BeanでSessionSynchronization
が実装されている場合、WebLogic Server EJBコンテナではトランザクション時にBeanに対するコールバックはほとんど行われません。登録されたオブジェクトがbeforeCompletion
コールバックを受け取ったときに同期サイクルが発生する可能性があります。
通常、WebLogic Server EJBコンテナではトランザクションのコミット時にBeanに対して次のコールバックが行われます。
-
afterBegin()
-
beforeCompletion()
-
afterCompletion()
EJBコンテナは、beforeCompletion
メソッドで他のBeanを呼び出すか、またはXAリソースを追加することができます。呼出しの回数は、beforeCompletionIterationLimit
属性によって制限されます。この属性は、トランザクションがロールバックされるまでに処理されるコールバックのサイクル数を指定します。同期サイクルは、登録されているオブジェクトがbeforeCompletion
コールバックを受信し、リソースが追加されるか、または以前に同期されていたオブジェクトが再登録されたときに発生します。反復制限を利用することで、同期サイクルが無限に繰り返されることを防止できます。
トランザクション・タイムアウトの設定
EJBアプリケーションのトランザクションには、タイムアウトを指定できます。トランザクションの存続期間がタイムアウトの設定値を超えた場合、トランザクション・サービスによってそのトランザクションは自動的にロールバックされます。
ノート:
トランザクションでbegin()
を実行する前に、タイムアウトを設定する必要があります。タイムアウトを設定しても、すでに開始されているトランザクションには反映されません。
タイムアウトの指定方法は、トランザクションの種類によって異なります。
-
コンテナ管理のトランザクション: Beanプロバイダは、
weblogic-ejb-jar.xml
デプロイメント記述子でtrans-timeout-seconds属性を構成します。 -
Bean管理のトランザクション: アプリケーションによって
UserTransaction.setTransactionTimeout
メソッドが呼び出されます。
ノート:
DBMSには、XAトランザクションがロックを保持できる期間を指定するための、DISTRIBUTED_LOCK_TIMEOUT
設定が用意されています。これがJTAタイムアウトより小さい場合、DBMSはトランザクションを中断します。
EJBトランザクションでの例外処理
WebLogic Server EJBアプリケーションでは、トランザクションの途中でスローされた特定の例外を取得して処理する必要があります。
例外処理の詳細は、EJB仕様2.1の第17章「Exception Handling」を参照してください。
EJBトランザクションでビジネス・メソッドによって例外がどのようにスローされるのかについては、セクション17.3にある表12 (コンテナ管理のトランザクション)および表13 (Bean管理のトランザクション)を参照してください。
クライアントの観点から見た例外については、セクション17.4を参照してください。特に、セクション12.4.1 (アプリケーション例外)、セクション17.4.2 (java.rmi.RemoteException
)、セクション17.4.2.1 (javax.transaction.TransactionRolledBackException
)、およびセクション17.4.2.2 (javax.transaction.TransactionRequiredException
)の参照をお薦めします。