目次 | 前
| 次
11. トランザクションに対するサポート
エンタプライズJavaBeansのキー機能の一つは,分散トランザクションに対するサポートとする。エンタプライズJavaBeansによって,アプリケーション開発者は複数のサイトに分散している可能性のある複数のデータベースで,データを自動的に更新するアプリケーションを書き込むことができる。サイトは,異なるベンダからのEJBサーバ及びコンテナを使用するかもしれない。
11.では,セションBeanと実体Beanとの区別はない。両者は同じものとして扱う。
エンタプライズBean開発者又はクライアントプログラマが分散トランザクションの複合度に直面することはない。トランザクションの管理の負担は,コンテナ及びEJBサーバ提供者にシフトされている。コンテナは,11.で後述する定義での宣言トランザクション適用範囲を実装する。EJBサーバは必要な低レベルトランザクションプロトコルを実装する。低レベルトランザクションプロトコルは,例えば,トランザクション管理者と,データベースシステム,トランザクション文脈伝播,分散二段階コミットなどとの間の二層コミットプロトコルなどを示す。
11.1 トランザクションモデル
エンタプライズJavaBeansは,OMG Object Transaction Service1.1(OTS)後にモデル化されたフラットトランザクションをサポートする。transaction-enabledであるエンタプライズBeanオブジェクトは,OTSで記述されるTransactionalObjectに相当する(エンタプライズBeanについては,将来的に復元可能なオブジェクトとして動作できるバージョンがリリースされるかもしれない)。
注:ネストトランザクションをサポートしないのは,現存のトランザクション処理及びデータベース管理システムのベンダがエンタプライズJavaBeansに対するサポートを組み込めるためとする。これらのベンダが将来入れ子トランザクションに対するサポートを提供する場合,エンタプライズJavaBeansは入れ子トランザクションの活用のため拡張されるかもしれない。
11.2 JTSとの関係
エンタプライズJavaBeansは,高レベル部品フレームワークであり,システムの複合度をアプリケーション開発者からの隠ぺいを試みる。そのため,ほとんどのエンタプライズBeans及びそのクライアントは,プログラム的にトランザクション管理をアクセスする必要はない。プログラム的にトランザクション適用範囲を制御しなければならないクライアント及びBeansは,Java
Transaction Service(JTS)APIの一部として定義されているインタフェースjavax.jts.UserTransactionを使用することとする。インタフェースjavax.jts.UserTransactionは,EJBコンテナ提供者がEJBをサポートするため実装しなければならない唯一のJTSインタフェースとする。
Java Transaction Service(JTS)APIは,Javaプラットフォーム上のトランザクション管理に関するすべてのJavaプログラム言語インタフェースを定義する。現段階で,JTSは次のものを備えている。
-
パッケージjavax.jtsはアプリケーションレベルの区分インタフェースとする。このパッケージは,EJB環境でトランザクション境界を明示的に区分したいと考えるBean実装者(TX_BEAN_MANAGEDBeansに対する)及びJavaプログラム言語のクライアントによって使用されることを意図している。パッケージjavax.jtsは,現存のどのトランザクション管理者にも簡単に実装できるインタフェースを定義する。
-
OTS1.1APIのJavaプログラム言語マッピング。これは,JavaIDLマッピングを使用するOMG規定のJavaプログラム言語マッピングとする。このAPIは,CORBAプログラマがJavaプログラム言語を使用してCORBAオブジェクトを実装することを意図している。このAPIに対するサポートは,EJB環境では必須ではない。ベンダはEJBサーバとコンテナとの間のインタフェースの一部としてこのAPIの使用を選択するかもしれないが,ベンダは同様に自由に他のAPIを使用できる点に注意すること。
-
標準X/Open XAインタフェースのJavaプログラム言語マッピング。これは,JDBCドライバのような資源管理者を外部トランザクション管理者に接続するためのAPIとする。EJBサーバ及び/又はコンテナは,このAPIを使用してデータベースドライバに接続できる。このAPIは,JDBC2.0の規定の一部として提案され,再検討されている。
11.3 シナリオ
11.3では,いくつかのシナリオを記述してエンタプライズJavaBeansの分散トランザクション能力を図示する。
11.3.1 複数データベースの更新
エンタプライズJavaBeansによって,アプリケーションプログラムは単一トランザクションで複数のデータベースのデータを更新できる。
図11.1では,クライアントがエンタプライズBean Xを呼び出している。Xは二つのデータベースA及びBのデータを更新する。その後,Xは他のエンタプライズBean
Yを呼び出す。YはデータベースCのデータを更新する。データベースA,B及びCへの更新は,すべてコミットされるか又はすべてロールバックされるかであり、EJBサーバがいずれかを確実に実行する。
 |
図11.1 複数データベースの更新
アプリケーションプログラマは,トランザクションセマンティクスを確実にするために特別なことをする必要はない。エンタプライズBean
X及びYは,標準JDBC APIを使用してデータベース更新を実行する。裏で,EJBサーバは,トランザクションの一部としてデータベース接続に参加する。トランザクションがコミットすると,EJBサーバ及びデータベースシステムは,二層コミットプロトコルを実行して,三つのデータベースすべてを交差した原始的更新を確実にする。
11.3.2 複数EJBサーバを介したデータベース更新
エンタプライズJavaBeansによって,複数サイトでのデータの更新が単一トランザクションで実行できる。
図11.2では,クライアントがエンタプライズBean Xを呼び出す。XはデータベースAのデータを更新し,遠隔EJBサーバにインストールされている別のエンタプライズBean
Yを呼び出す。YはデータベースBのデータを更新する。エンタプライズJavaBeansによって,単一のトランザクションとしてデータベースA及びBへの更新を実行できる。
 |
図11.2 複数EJBサーバを介したデータベース更新
XがYを呼び出す場合,二つのEJBサーバは協調してXからYへトランザクション文脈を伝播する。このトランザクション文脈伝播はアプリケーションレベルのコードにはみえない。
トランザクションコミット時には,二つのEJBサーバが分散二層コミットプロトコル(機能が存在する場合)を使用して,データベース更新の原子性を確実にする。
11.3.3 クライアント管理区分
クライアント又は非トランザクションエンタプライズBeanオブジェクトは,インタフェースjavax.jts.UserTransactionを使用して,明示的にトランザクション境界を定めることができる。
図11.3に示すとおり,明示的なトランザクション区分を使用するクライアントプログラムは,複数のトランザクションサーバに存在する複数のデータベースを交差した原子間更新を実行するかもしれない。
 |
図11.3 クライアント管理区分
アプリケーションプログラマは,begin呼出し及びcommit呼出しでトランザクション境界を定め,EJBサーバは,データベースA及びデータベースBへの更新がトランザクションとなることを確認する。クライアント側のトランザクションサービスのプロキシーは自動的にトランザクション文脈を二つのEJBサーバに伝播する。クライアントプログラムがコミットを呼び出す場合,二つのEJBサーバは二層コミットプロトコルを実行する。
11.3.4 コンテナ管理区分
クライアントがエンタプライズBeanを呼び出す場合は,コンテナは,必ずメソッド呼出しに介入する。その介入によって,コンテナは,トランザクション属性を通じて宣言的にトランザクション区分を制御することができる。
例えば,エンタプライズBeanがトランザクション属性TX_REQUIREDで配置される場合,クライアントがトランザクション可能なエンタプライズBeanを呼び出すときは常に,コンテナは自動的にトランザクションを始める。一方でクライアントはトランザクション文脈と関連づけられない。
図11.4は次のシナリオを示している。非トランザクションクライアントがエンタプライズBean
Xを呼び出す。クライアントからのメッセージは,トランザクション文脈を含まないため,コンテナはX上の遠隔メソッドをディスパッチする前に,新しいトランザクションを起動する。Xの作動はトランザクションの文脈で実行される。Xが他のエンタプライズBeans(この場合,Y)を呼び出す場合,他のエンタプライズBeansが実行する作動も,自動的に,他のエンタプライズBeanのトランザクション属性の影響を受けるトランザクションに包含される。
 |
図11.4 コンテナ管理区分
コンテナは,Xがクライアントに応答を返す際に自動的にトランザクションをコミットする。
11.3.5 Bean管理区分
トランザクション属性TX_BEAN_MANAGEDを有するエンタプライズBeanは,インタフェースjavax.jts.UserTransactionを使用して,トランザクションの境界を定めることができる。
11.3.6 非Javaクライアント及びサーバとの相互運用性
エンタプライズJavaBeansは,Javaによって分散エンタプライズアプリケーションを書くためのJavaAPIを目標としているが,そういったアプリケーションであっても非Javaクライアント及び非Javaサーバとの相互運用性をもつことが望ましい。
コンテナによってエンタプライズBeanは非Javaクライアントからの呼出しが可能になる。例えば,エンタプライズJavaBeans※のCORBAマッピングによって,すべてのCORBAクライアントが,CORBAを使用できるサーバ上で標準CORBA
APIを使用してあらゆるエンタプライズBeanオブジェクトを呼び出してもよい。
 |
図11.5 標準CORBA APIを使ってCORBAクライアントがエンタプライズBeanオブジェクトを呼出す例
前述の相互運用性を可能にする橋渡しプロトコルを定義するのは,エンタプライズJavaBeansの適用範囲外とする。そのような橋渡しは,いくつかのEJBサーバによる付加価値とする。
現存のサーバアプリケーションへの接続性を提供することも同様に重要とする。EJBサーバは,メインフレーム上のCICSで実行するアプリケーションなどの現存のエンタプライズアプリケーションへのアクセス提供を選択するかもしれない。例えば,EJBサーバは現存のCICSプログラムがエンタプライズBeansにアクセス可能にする橋渡しを提供するかもしれない。橋渡しは,CICSプログラムをJavaプログラム言語をベースとする開発者対して可視にする。例えば,開発者には,CICSプログラムがEJBサーバ上で,あるコンテナにインストールされる他のエンタプライズbeanとして見える。
11.4 宣言トランザクション管理
エンタプライズBeanオブジェクト上でのクライアントメソッド呼出しには,すべてコンテナが介入する。介入によってトランザクション管理責任のコンテナへの委託が可能となる。
宣言トランザクション管理は,各エンタプライズBeanのホームコンテナと関連づけらるトランザクション属性によって制御される。コンテナ提供者のツールは,トランザクション属性の値を設定し,変更するため使用できる。
エンタプライズJavaBeansは,トランザクション属性として次に示す値を定義する。
-
TX_NOT_SUPPORTED
-
TX_BEAN_MANAGED
-
TX_REQUIRED
-
TX_SUPPORTS
-
TX_REQUIRES_NEW
-
TX_MANDATORY
トランザクション属性は,エンタプライズBeanの配置記述子で指定される。トランザクション属性は,すべてのメソッドに適用するために全体Beanと関連づけでき,又は個々のメソッドと関連づけができる。メソッドレベルの記述子を使用する場合は,15.2で定義された制限に従わなければならない。
11.4.1 TX_NOT_SUPPORTED
コンテナは,常にトランザクション適用範囲のないトランザクション属性TX_NOT_SUPPORTEDを有するエンタプライズBeanを呼び出さなければならない。クライアントがトランザクション適用範囲で呼出しを実行する場合,コンテナは,メソッド呼出しをエンタプライズBeanオブジェクトに委託する前に,現スレッドとトランザクション適用範囲との関連づけを中断する。エンタプライズBeanオブジェクト上のメソッド呼出しが完了すると,コンテナは中断された関連づけを再開する。
中断されたクライアントのトランザクション文脈は,資源又はエンタプライズBeanオブジェクトから呼び出される他のエンタプライズBeanオブジェクトに渡されない。
11.4.2 TX_BEAN_MANAGED
属性TX_BEAN_MANAGEDを有するエンタプライズBeanは,インタフェースjavax.jts.UserTransactionを使用して,トランザクション境界を区分する。TX_BEAN_MANAGEDトランザクションの規則は11.5で定義される。
11.4.3 TX_REQUIRED
トランザクション文脈と関連づけられる間に,クライアントがトランザクション属性TX_REQUIREDを有するエンタプライズBeanオブジェクトを呼び出す場合,コンテナは,クライアントのトランザクション文脈でエンタプライズBeanのメソッドを呼び出す。
トランザクション文脈と関連づけられない間に,クライアントがエンタプライズBeanオブジェクトを呼び出す場合,コンテナは,メソッド呼出しをエンタプライズBeanオブジェクトに委託する前に自動的に新しいトランザクションを起動し,エンタプライズBeanオブジェクト上でのメソッド呼出しが完了するとトランザクションのコミットを試みる。コンテナは,メソッドの結果がクライアントに送信される前にコミットプロトコルを実行する。
トランザクション文脈は,資源又はエンタプライズBeanオブジェクトから呼び出される他のエンタプライズBeanオブジェクトに渡される。
11.4.4 TX_SUPPORTS
トランザクション属性TX_SUPPORTSを有するエンタプライズBeanオブジェクトは,クライアントのトランザクション適用範囲で呼び出される。クライアントにトランザクション適用範囲がない場合,エンタプライズBeanは同様にトランザクション適用範囲なしで呼び出される。
トランザクション文脈がある場合は,資源又はエンタプライズBeanオブジェクトから呼び出される他のエンタプライズBeanオブジェクトに渡される。
11.4.5TX_REQUIRES_NEW
トランザクション属性TX_REQUIRES_NEWを有するエンタプライズBeanは,常に新しいトランザクション適用範囲で呼び出される。コンテナは,メソッド呼出しをエンタプライズBeanオブジェクトに委託する前に新しいトランザクションを起動し,エンタプライズBeanオブジェクト上のメソッド呼出しが完了するとトランザクションのコミットを試みる。コンテナは,メソッドの結果がクライアントに送信される前にコミットプロトコルを実行する。
クライアント要求がトランザクションと関連づけられる場合,関連づけは,新しいトランザクションが起動される前に中断され,新しいトランザクションが完了すると再開される。
新しいトランザクション文脈は,資源又はエンタプライズBeanオブジェクトから呼び出される他のエンタプライズBeanオブジェクトに渡される。
11.4.6 TX_MANDATORY
TX_MANDATORY属性を有するエンタプライズBeanオブジェクトは,常にクライアントのトランザクションの適用範囲で呼び出される。クライアントがトランザクション文脈のないエンタプライズBeanの呼出しを試みる場合,コンテナはクライアントに例外TransactionRequiredを投げる。
クライアントのトランザクション文脈は,資源又はエンタプライズBeanオブジェクトから呼び出される他のエンタプライズBeanオブジェクトに渡される。
11.4.7 トランザクション属性要約
表11.1は,トランザクション属性及びクライアントのトランザクション文脈の機能としてエンタプライズBeanオブジェクトメソッド上のメソッドが実行するトランザクション適用範囲の要約とする。
表11.1 宣言的トランザクション属性の効果
トランザクション属性 |
クライアントのトランザクション |
エンタプライズBeanのメソッドに関連付けられたトランザクション |
TX_NOT_SUPPORTED |
- |
- |
T1 |
- |
TX_REQUIRED |
- |
T2 |
T1 |
T1 |
TX_SUPPORTS |
- |
- |
T1 |
T1 |
TX_REQUIRES_NEW |
- |
T2 |
T1 |
T2 |
TX_MANDATORY |
- |
error |
T1 |
T1 |
ダッシュは,“大域的トランザクション文脈が存在しない又は伝播しない”ことを意味する。コンテナは,あらゆるトランザクションの外部で又は局所トランザクションとしてメソッドを実行できる。
11.5 トランザクションTX_BEAN_MANAGED
属性TX_BEAN_MANAGEDを有するエンタプライズBeanは,インタフェースjavax.jts.UserTransactionを使用してトランザクション境界を区分することができる。
コンテナは,インタフェースjavax.jts.UserTransactionをメソッドEJBContext.getUserTransaction()を通じたエンタプライズBeanの利用を可能にする。その例を次に示す。
import javax.jts.UserTransaction;
...
EJBContext ic = ...;
...
UserTransaction tx = ic.getUserTransaction();
tx.begin();
... // do work
tx.commit();
TX_BEAN_MANAGED以外のトランザクション属性で配置されるエンタプライズBeansは,使用中のトランザクション管理者を直接アクセスできない。コンテナは,インタフェースjavax.jts.UserTransactionをこれらのエンタプライズBeansにとって利用不可にする。
11.5.1 状態付きセションBeansに関するTX_BEAN_MANAGEDの規定
コンテナは,次のとおりTX_BEAN_MANAGED Bean上でトランザクションを管理しなければならない。クライアントが状態付きTX_BEAN_MANAGED
Beanを呼び出す場合,コンテナは,あらゆる到着トランザクションを中断する。コンテナによって,セションインスタンスは,インタフェースbegin
javax.jts.UserTransactionを使用してトランザクションを始めることができる。インスタンスは,トランザクションと関連づけられ,トランザクション終了までその関連づけは変わらない。Beanによって始められたトランザクションがインスタンスと関連づけられると,インスタンス上のメソッドは,そのトランザクションに従って実行する。
トランザクションを始めた業務メソッドは,トランザクションをコミット又はロールバックしないで完了できる。コンテナは,トランザクション終了まで,トランザクションと複数のクライアント呼出しを交差するインスタンスとの間の関連づけを保持しなければならない。
コンテナが実行する動作を表11.2に要約する。
表11.2 TX_BEAN_MANAGEDセションBean
クライアントのトランザクション |
インスタンスと現在関連付けられているトランザクション |
メソッドと関連付けられたトランザクション |
- |
- |
- |
T1 |
- |
- |
- |
T3 |
T3 |
T1 |
T3 |
T3 |
次に表の項目を詳細に説明する。
-
クライアント要求がトランザクションと関連づけられず,インスタンスがトランザクションと関連づけられない場合,コンテナはトランザクション文脈のないインスタンスを呼び出す。
-
クライアントがトランザクションと関連づけられ,インスタンスがトランザクションと関連づけられない場合,コンテナは,クライアントのトランザクション関連づけを中断し,トランザクション文脈のないメソッドを呼び出す。メソッドが完了すると,コンテナはクライアントのトランザクション関連づけを再開する。
-
クライアント要求がトランザクションと関連づけられず,インスタンスがすでにトランザクションと関連づけられている場合,コンテナは,インスタンスと関連づけられたトランザクションを有するインスタンスを呼び出す。
-
クライアントがトランザクションと関連づけられ,インスタンスがすでにトランザクションと関連づけられている場合,コンテナは,クライアントのトランザクション関連づけを中断し,インスタンスと関連づけられたトランザクション文脈を有するメソッドを呼び出す。メソッドが完了すると,コンテナはクライアントのトランザクション関連づけを再開する。
どのケースでも,メソッド完了時にインスタンスがトランザクションと関連づけられている場合(つまり,インスタンスがまだトランザクションを完了していない場合),コンテナはクライアントに制御を返す前にトランザクションを中断する。
Beanがメソッドでいくつかのトランザクションを順次実行することは,文法に合っている。
インスタンスが現トランザクションの完了前に,新しいトランザクションの起動を試みることは不当とする。
11.5.2 無状態セションズ及び実体Beanに関するTX_BEAN_MANAGED規定
無状態セションBeans及びすべての実体Beansに対するTX_BEAN_MANAGEDトランザクションの振舞いに関する規定は,状態付きセションBeansに関する規定と同一とするが,重要な例外が一つある。無状態セションBeanのインスタンス又は実体Beanのインスタンスがクライアントからの複数の呼出しを交差したトランザクションとの関連づけを保持することは許可されない。つまり,業務メソッドがトランザクションを始める場合,メソッドは,返される前にトランザクションを完了(コミット又はロールバック)しなければならないということとする。
セションBeanのインスタンスが永久的に単一のクライアントと関連づけられるため,トランザクションをクライアントからの複数の呼出しを交差するインスタンスに関連づけることは状態付きセションBeanにとって意味がある。複数のクライアント呼出しを交差するトランザクション関連づけを保持しても,インスタンスは一般に複数のクライアント間で共用されているため,実体Beans又は無状態セションBeansにとっては意味がない。
11.6トランザクション分離レベル
エンタプライズBean提供者は,要求されたトランザクション分離レベルを配置記述子で指定する。可能な分離レベルは次のとおりとする。
-
TRANSACTION_READ_UNCOMMITTED
-
TRANSACTION_READ_COMMITTED
-
TRANSACTION_REPEATABLE_READ
-
TRANSACTION_SERIALIZABLE
前述の分離レベルは,JDBC分離レベルに対応し,クラスjavax.ejb.deployment.ControlDescriptorで定義される。
備考: EJBはJDBC TRANSACTION_NONE分離レベルを使用できない点に注意すること。
コンテナは,次の方法によって配置記述子で提供されるトランザクション分離レベル情報を使用する。
-
Bean管理永続性を有するセションBeans及び実体Beansに関しては,コンテナは,指定されたトランザクション分離レベルが各トランザクション起動時にBeanが使用するデータベース接続で設定されることを確実にする。
-
コンテナ管理永続性を有する実体Beansに関しては,コンテナツールが生成したデータベースアクセス呼出しが,指定された分離レベルを実現しなければならない。
11.7 配置記述子制限
トランザクション属性及び分離レベルは,完全エンタプライズBean及び各エンタプライズBeanのメソッドに対して指定できる。値がメソッドレベルで指定される場合,Beanレベルで指定された値に優先する。
11.7では,メソッドレベルでのトランザクション属性及び分離レベルの使用における制限を定義する。
11.7.1 TX_BEAN_MANAGED
TX_BEAN_MANAGEDトランザクション属性値と他のトランザクション属性値を混合してはならない。つまり,Beanレベルの記述子又はメソッドレベルの記述子の一つが属性TX_BEAN_MANAGEDを指定する場合,メソッドレベルの記述子が存在するなら,メソッドレベルの記述子はすべてTX_BEAN_MANAGEDを指定しなければならない。
コンテナは配置時にこのエラーを検出し,配置者に知らせる。
11.7.2 セションBean
クライアントが明示的なトランザクション区分を実行する場合,次に示す状態に誘導するインスタンス上でメソッドのシーケンスを呼び出してはならない。
-
インスタンスがトランザクションと関連づけられる状態。及び
-
11.で記述したトランザクション属性の規則を使用して,コンテナが異なるトランザクション又はトランザクションなしでBean上でメソッドを呼び出す必要がある状態。
コンテナはこのような試行を検出し,クライアントにjava.rmi.RemoteExceptionを投げ,エラーを記録してシステム管理者に知らせなければならない。
例えば,method1がTX_REQUIRED属性で配置され,method2がTX_REQUIRES_NEWで配置される場合,クライアントがトランザクションを起動し,セションBean上でmethod1及びmethod2を呼び出すのはエラーとする。
11.7.3 分離レベル
メソッドレベルの記述子を使用する場合,記述子で指定された分離レベルは一貫性をもって使用されなければならない。そうすればメソッドは,インスタンスと関連づけられる分離レベルとは異なる分離レベルを必要としなくなる。コンテナはそういった条件を検出し,クライアントにjava.rmi.RemoteExceptionを投げなければならない。コンテナは,エラーを記録し,システム管理者に知らせなければならない。
例えば,エンタプライズBeanのトランザクション属性がTX_REQUIREDとなるとすると,method1及びmethod2に対して指定された分離レベルが異なる場合に,クライアントがトランザクションを起動し,エンタプライズBean上でmethod1及びmethod2を呼び出すことはエラーとする。
この規則は,セションエンタプライズBeansにも実体エンタプライズBeansにも適用される。
11.8 トランザクション管理及び例外
EJBサーバ及びEJBコンテナは,JTS規定で定義される状態で例外TransactionRolledbackException,例外TransactionRequiredException及び例外InvalidTransactionExceptionを投げることがある。これらの例外の参照ページについては附属書Bを参照のこと。
目次 | 前
| 次