ここでは、以下について説明します。
トランザクションの制御方法や実行時の制御内容などを詳細に決定するために、トランザクション管理種別とトランザクション属性を定義します。
トランザクション管理種別
トランザクション管理種別とは、EJBアプリケーションのトランザクションを制御するための定義を行うもので、EJBアプリケーションごとに定義します。
トランザクション管理種別には、“Bean”と“Container”の2つがあります。以下に、各トランザクション管理種別の詳細を示します。
トランザクション管理種別 | 内容 |
---|---|
Bean | UserTransactionインタフェースを使用して、EJBアプリケーションがトランザクションの制御を行います。 |
Container | トランザクション制御はコンテナが行います。 |
注意
トランザクション管理種別がContainerの場合、javax.transaction.UserTransactionインタフェースを使用してトランザクションを制御しようとすると、IllegalStateExceptionが発生します。
トランザクション属性とは、実行時にコンテナが行うトランザクション制御の内容を指定するもので、トランザクション管理種別に“Container”を指定した場合に指定します。
EJBアプリケーションごと、または、EJBアプリケーションのメソッド単位で指定します。
以下に、各トランザクション属性の詳細を示します。
トランザクション属性 | 内容 | Session Bean | Entity Bean | Message-driven Bean |
---|---|---|---|---|
Mandatory | この属性を指定したEJBアプリケーション(メソッド)は、常に呼出し元で開始されているトランザクションで実行されます。
| ○ | ○ | - |
Required | この属性を指定したEJBアプリケーション(メソッド)は、常にトランザクションが開始された状態で実行されます。呼出し元でトランザクションが開始されている場合と開始されていない場合で、トランザクションが異なります。
通常、メソッド実行完了後、トランザクションがcommitされます。当属性が指定されたBean(メソッド)内でトランザクションをrollbackする必要がある場合、SessionContext/EntityContext/MessageDrivenContextインタフェースのsetRollbackOnlyメソッドを使用してトランザクションをrollbackするようマーク(宣言)できます。 注) Message-driven Beanでこの属性を指定して、無条件にsetRollbackOnlyメソッドを使用してメッセージ受信をロールバックすると、メッセージの配信が繰り返されてループする可能性があります。処理を継続できないようなエラーが発生した場合には、setRollbackOnlyメソッドを実行するのではなく、EJBExceptionをthrowするなどして異常時のメッセージ退避機能を使用してください。 | ○ | ○ | ○ |
Supports | この属性を指定したEJBアプリケーション(メソッド)は、呼出し元でトランザクションが開始されている場合と開始されていない場合で、実行される状態が異なります。
この属性は、トランザクションの一貫性・整合性が保たれない可能性があることから、EJB規約では推奨していません。 | ○ | ○ | - |
RequiresNew | この属性を指定したEJBアプリケーション(メソッド)は、常にコンテナで開始されたトランザクションで実行されます。
この属性を指定すると、トランザクション排他処理の範囲を縮小してデータベースの占有を防止できます。 | ○ | ○ | - |
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() | すべてのビジネスメソッド | create() | すべてのビジネスメソッド |
Message-driven Beanは、メッセージリスナメソッドにトランザクション属性を設定するか、またはEJBアプリケーション(Bean単位)でトランザクション属性を指定してください。
EJBアプリケーション(Bean単位)でトランザクション属性を指定し、そのEJBアプリケーションの各メソッドすべてに対してトランザクション属性を指定した場合、メソッドの種類によっては重複した設定となります。このような場合はメソッドへの指定が優先されます。
例外が発生した場合、呼出し元に例外の通知を行います。例外発生時の詳細は、“15.5.2 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) イベントログ、または、システムログにエラーメッセージ“IJServer: エラー: IJServer21061: トランザクションが開始されています”が出力される
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つのデータソースに限定するようにしてください。
データソースは、Interstage管理コンソールまたはisj2eeadminコマンドで設定します。
分散トランザクション機能を使用することにより、複数のトランザクション処理を1つのトランザクションとして扱うことができます。
分散トランザクションの指定はIJServerの定義時に指定します。
指定方法について、Interstage管理コンソールを使用する場合は、Interstage管理コンソールのヘルプを参照してください。isj2eeadminコマンドを使用する場合は“リファレンスマニュアル(コマンド編)”の“isj2eeadmin”を参照してください。
“分散トランザクション機能”についての詳細は、“第5部 JTS/JTA編 ”を参照してください。