Interstage Application Server J2EE ユーザーズガイド
|
目次
索引
|
9.5.1 トランザクション管理種別とトランザクション属性
本章では、以下について説明します。
トランザクションの制御方法や実行時の制御内容などを詳細に決定するために、トランザクション管理種別とトランザクション属性を定義します。
トランザクション管理種別とは、EJBアプリケーションのトランザクションを制御するための定義を行うもので、EJBアプリケーションごとに定義します。
トランザクション管理種別には、“Bean”と“Container”の2つがあります。以下に、各トランザクション管理種別の詳細を示します。
トランザクション管理種別 |
内容 |
Bean |
UserTransactionインタフェースを使用して、EJBアプリケーションがトランザクションの制御を行います。
この管理種別を指定できるEJBアプリケーションは、Session BeanとMessage-driven Beanです。
Session Beanでは、呼出し元でトランザクションが開始されている場合は、コンテナがそのトランザクションを中断します。処理が終了した後、中断していた呼出し元のトランザクションを再開します。
Message-driven Beanでは、メッセージの受信はトランザクションに含まれません。Destinationに送信されたメッセージはonMessageメソッドが終了した時点でJMSが自動的に受信確認(acknowledge)を行い、メッセージの受信を完了します。 |
Container |
トランザクション制御はコンテナが行います。
EJBアプリケーションにトランザクション処理の記述をしなくてよいため、EJBアプリケーションのポータビリティが向上し、最小単位の部品としてEJBアプリケーションを作成できます。
この管理種別を指定した場合、実行時のトランザクション制御内容を指定するために、“トランザクション属性”を指定してください。 |
トランザクション管理種別がContainerの場合、javax.transaction.UserTransactionインタフェースを使用してトランザクションを制御しようとすると、IllegalStateExceptionが発生します。
トランザクション属性とは、実行時にコンテナが行うトランザクション制御の内容を指定するもので、トランザクション管理種別に“Container”を指定した場合に指定します。
EJBアプリケーションごと、または、EJBアプリケーションのメソッド単位で指定します。
以下に、各トランザクション属性の詳細を示します。
トランザクション属性 |
内容 |
Session Bean |
Entity Bean |
Message-driven Bean |
Mandatory |
この属性を指定したEJBアプリケーション(メソッド)は、常に呼出し元で開始されているトランザクションで実行されます。
- 呼出し元でトランザクションが開始されている場合
呼出し元のトランザクションで実行されます。
- 呼出し元でトランザクションが開始されていない場合
呼出し元にTransactionRequiredExceptionが返却されます。 |
○ |
○ |
− |
Required |
この属性を指定したEJBアプリケーション(メソッド)は、常にトランザクションが開始された状態で実行されます。呼出し元でトランザクションが開始されている場合と開始されていない場合で、トランザクションが異なります。
- 呼出し元のトランザクションで開始されている場合
呼出し元のトランザクションで実行されます。
- 呼出し元でトランザクションが開始されていない場合
コンテナがトランザクションを開始し、そのトランザクションで実行されます。開始されたトランザクションはメソッド実行完了後、コンテナにより終了(commit/rollback)されます。
通常、メソッド実行完了後、トランザクションがcommitされます。当属性が指定されたBean(メソッド)内でトランザクションをrollbackする必要がある場合、SessionContext/EntityContext/MessageDrivenContextインタフェースのsetRollbackOnlyメソッドを使用してトランザクションをrollbackするようマーク(宣言)できます。
一般的に、Entity Beanでこの属性を使用すると、可搬性の高いEJBアプリケーションを作成できます。
Message-driven Beanの場合、メッセージの受信もトランザクションに含まれます。Message-driven Beanにメッセージが配信されると、コンテナがトランザクションを開始してからonMessageメソッドにメッセージを渡します。
Message-driven Beanでこの属性を指定して、無条件にsetRollbackOnlyメソッドを使用してメッセージ受信をロールバックすると、メッセージの配信が繰り返されてループする可能性があります。処理を継続できないようなエラーが発生した場合には、setRollbackOnlyメソッドを実行するのではなく、EJBExceptionをthrowするなどして異常時のメッセージ退避機能を使用してください。 |
○ |
○ |
○ |
Supports |
この属性を指定したEJBアプリケーション(メソッド)は、呼出し元でトランザクションが開始されている場合と開始されていない場合で、実行される状態が異なります。
- 呼出し元でトランザクションが開始されている場合
呼出し元のトランザクションで実行されます。
- 呼出し元でトランザクションが開始されていない場合
トランザクションが開始されていない状態のまま処理が実行されます。
この属性は、トランザクションの一貫性・整合性が保たれない可能性があることから、EJB規約では推奨していません。 |
○ |
○ |
− |
RequiresNew |
この属性を指定したEJBアプリケーション(メソッド)は、常にコンテナで開始されたトランザクションで実行されます。
- 呼出し元でトランザクションが開始されている場合
コンテナが、呼出し元のトランザクションを中断します。その後、コンテナで開始されたトランザクションで実行されます。開始されたトランザクションは、メソッド実行完了後、コンテナにより終了(commit/rollback)されます。処理が終了した後、コンテナは、中断していた呼出し元のトランザクションを再開します。通常、メソッド実行完了後、トランザクションがcommitされます。当属性が指定されたBean(メソッド)内でトランザクションをrollbackする必要がある場合、SessionContext/EntityContextインタフェースのsetRollbackOnlyメソッドを使用してトランザクションをrollbackするようマーク(宣言)できます。
- 呼出し元でトランザクションが開始されていない場合
コンテナがトランザクションを開始し、そのトランザクションで実行されます。開始されたトランザクションは、メソッド実行完了後、コンテナにより終了(commit/rollback)されます。通常、メソッド実行完了後、トランザクションがcommitされます。当属性が指定されたBean(メソッド)内でトランザクションをrollbackする必要がある場合、SessionContext/EntityContextインタフェースのsetRollbackOnlyメソッドを使用してトランザクションをrollbackするようマーク(宣言)できます。
この属性を指定すると、トランザクション排他処理の範囲を縮小してデータベースの占有を防止できます。 |
○ |
○ |
− |
NotSupported |
この属性を指定したEJBアプリケーション(メソッド)は、常にトランザクションが開始されていない状態で実行されます。
- 呼出し元でトランザクションが開始されている場合
コンテナが、そのトランザクションを中断します。処理が終了した後、コンテナは、中断していた呼出し元のトランザクションを再開します。
- 呼出し元でトランザクションが開始されていない場合
トランザクションが開始されていない状態のまま処理が実行されます。
Message-driven Beanの場合、メッセージが配信された時点でコンテナがメッセージの受信を完了します。 |
○ |
○ |
○ |
Never |
この属性を指定したEJBアプリケーション(メソッド)は、常にトランザクションが開始されていない状態で実行されます。
- 呼出し元でトランザクションが開始されている場合
呼出し元に例外が返却されます。
- 呼出し元でトランザクションが開始されていない場合
トランザクションが開始されていない状態のまま処理が実行されます。 |
○ |
○ |
− |
○:サポート
−:用途なし
呼出し先のBeanに指定するトランザクション属性により、呼出し先のBeanと呼出し元のトランザクションの制御状態は以下のようになります。
呼出し先のBeanに指定した
トランザクション属性 |
呼出し元での
トランザクションの状態 |
呼出し先での
トランザクションの状態 |
NotSupported |
none |
none |
T1 |
none |
Required |
none |
T2 |
T1 |
T1 |
Supports |
none |
none |
T1 |
T1 |
RequiresNew |
none |
T2 |
T1 |
T2 |
Mandatory |
none |
error |
T1 |
T1 |
Never |
none |
none |
T1 |
error |
none:トランザクションが開始されていない状態
T1:呼出し元で開始したトランザクションで動作している状態
T2:呼出し先で開始したトランザクションで動作している状態
error:エラーが発生
Mandatory、RequiredおよびSupportsを使用して、呼出し元のトランザクション(T1)で呼出し先のBeanを動作させる場合、以下の機能を使用してください。以下の機能を使用しない場合には、呼出し元のトランザクションは開始されていない状態(none)と判断して動作します。
- 分散トランザクションを使用しない
呼出し元のEJBアプリケーションと、呼出し先のEJBアプリケーションを同一JavaVM上で動作させる。
- 分散トランザクションを使用する
呼出し元が、クライアントアプリケーションまたはJava VM外のEJBアプリケーションの場合、分散トランザクションを使用してトランザクションを連携する。
トランザクション属性を指定するときは、以下の点に注意してください。
- トランザクション属性をメソッド単位で指定する場合、指定できるメソッドは限られています。以下に、トランザクション属性が指定できるメソッドを示します。
Bean種別 |
Homeインタフェースメソッド |
Remoteインタフェースメソッド |
LocalHomeインタフェースメソッド |
Localインタフェースメソッド |
Session Bean |
なし |
すべてのビジネスメソッド |
すべてのビジネスメソッド |
すべてのビジネスメソッド |
Entity Bean |
create()
findByPrimaryKey()
finderメソッド
ejbHomeメソッド
remove(java.lang.Object)
remove(javax.ejb.Handle) |
すべてのビジネスメソッド
remove() |
create()
findByPrimaryKey()
finderメソッド
ejbHomeメソッド
remove(java.lang.Object) |
すべてのビジネスメソッド
remove() |
- Message-driven Beanは、onMessageメソッドにトランザクション属性を設定するか、またはEJBアプリケーション(Bean単位)でトランザクション属性を指定してください。
- EJBアプリケーション(Bean単位)でトランザクション属性を指定し、そのEJBアプリケーションの各メソッドすべてに対してトランザクション属性を指定した場合、メソッドの種類によっては重複した設定となります。このような場合はメソッドへの指定が優先されます。
- 例外が発生した場合、呼出し元に例外の通知を行います。例外発生時の詳細は、“EJBサービスが提供するトランザクション制御の例外処理”を参照してください。
- EJB規約により、トランザクション種別に“Container”が指定されたSTATEFULのSession Beanのインスタンスが1度に参加できるトランザクションは1つだけです。呼出し元で開始しているトランザクションに参加しているインスタンスに対して、“NotSupported”または、“RequiresNew”のどちらかのトランザクション属性が指定されたメソッドが呼び出された場合、java.rmi.RemoteExceptionが呼出し元へ返却されます。
- トランザクション属性が指定されていないメソッドが存在する場合、コンテナは自動的に“Required”が指定されたものとしてトランザクションの制御を行います。
- トランザクション管理種別に“Container”、トランザクション属性にMandatory/Required/Supportsを指定したSTATEFUL Session Beanを使用するEJBアプリケーションを開発する場合、STATEFUL Session Beanの開放(remove)について以下の点に注意してください。
- STATEFUL Session Beanを呼び出すEJBアプリケーションでトランザクションの操作を行う場合、STATEFUL Session Beanの開放処理(removeメソッド)は、必ずビジネスメソッド実行時に開始されているトランザクション処理が、完了したあとに行ってください。トランザクション処理中に開放処理(removeメソッド)を行った場合は、以下のエラーが発生します。
1)javax.ejb.RemoveExceptionが呼び出し元に返却される
2)イベントログ、または、システムログにエラーメッセージ“EJB: エラー: EJB1061: トランザクションが開始されています”が出力される
■ EJBサービスが提供するトランザクション機能を使用する場合の注意事項
EJBサービスが提供するトランザクション機能を使用する場合、以下の点に注意してください。
- 分散トランザクションを使用しない場合、javax.transaction.UserTransactionインタフェースでJMSのトランザクション制御を行うことはできません。
JMSのトランザクション制御を行う場合は、分散トランザクション機能を使用して、javax.transaction.UserTransactionインタフェースでJMSのトランザクションを制御するか、または、JMSのトランザクション機能を使用してJMSの制御を行ってください。
- javax.transaction.UserTransactionインタフェースで、JDBCのトランザクション制御を行う場合、UserTransaction.begin()メソッド発行後、複数のデータソースにアクセスすると、データソースごとに別々のトランザクションとなります。
この状態でUserTransaction.commit()メソッドを発行すると、関連するすべてのトランザクションが順番にコミットされます。
コミットは、コンテナによって1フェーズコミットメントプロトコルで処理されるため、コミットされるトランザクションとロールバックされるトランザクションが混在する可能性があります。
このため、javax.transaction.UserTransactionインタフェースのbegin()メソッドからcommit()メソッドの間で、更新するデータベースを1つのデータソースに限定するようにしてください。
ただし、分散トランザクション機能を使用することにより、複数のトランザクション処理を1つのトランザクションとして扱うことができます。
データソースは、Interstage管理コンソールで設定します。
分散トランザクションの指定はIJServerの定義時に指定します。指定方法についてはInterstage管理コンソールのヘルプを参照してください。“分散トランザクション機能”についての詳細は、JTS/JTA編を参照してください。
- 9.5.1.1 各トランザクション管理種別と各トランザクション属性の制御例
- 9.5.1.2 トランザクション管理種別と属性の設定方法
All Rights Reserved, Copyright(C) 富士通株式会社 2005