Oracle® Fusion Middleware Oracle WebLogic Server JTA プログラマーズ ガイド 11g リリース 1 (10.3.1) B55540-01 |
|
戻る |
次へ |
この章では次の内容について説明します。
この節の内容は以下のとおりです。
WebLogic Server の最も基本的な機能の 1 つはトランザクション管理です。トランザクションは、データベースの変更を正確に完了させるための手段です。また、トランザクションによって、以下のような高性能トランザクションのすべての ACID プロパティがデータベース トランザクションに備わります。
原子性 - トランザクションによるデータベースへの変更はすべて 1 つの単位として行われ、そうでない場合にはすべての変更がロールバックされます。
一貫性 - トランザクションが正常に実行されると、データベースが前の有効状態から新しい有効状態に変化します。
隔離性 - トランザクションによるデータベースへの変更は、トランザクションが処理を完了するまで他の処理からは見えません。
持続性 - トランザクションによるデータベースへの変更は、システムまたは媒体の障害が発生しても失われません。
WebLogic Server はデータベースの更新が正確に行われるようにする優れたインフラストラクチャを備えているので、さまざまなリソース マネージャにまたがる場合であってもトランザクションの整合性が保護されます。1 つの処理でエラーが起きた場合は、関連するすべての処理がロールバックされます。
WebLogic Server では、Sun Microsystems の Java Platform, Enterprise Edition (Java EE) プログラミング モデルのトランザクションがサポートされています。また、WebLogic Server では、エンタープライズ JavaBeans (EJB) 仕様 3.0 に準拠して、エンタープライズ JavaBean を使用する Java アプリケーションのトランザクションが完全にサポートされているほか、Java Transaction API (JTA) 仕様 1.1 もサポートされています。この 2 つの仕様はどちらも、Sun Microsystems が発行しているもので、それぞれ以下の URL からアクセスできます。
仕様 | 場所 |
---|---|
EJB 3.0 | http://java.sun.com/products/ejb/docs.html |
JTA 1.1 | http://java.sun.com/products/jta/index.html |
WebLogic Server では、Sun Microsystems の Java Transaction API (JTA) がサポートされています。JTA は、以下のアプリケーションで使用されます。
WebLogic Server EJB コンテナ内のエンタープライズ JavaBean (EJB) アプリケーション
WebLogic Server インフラストラクチャ内の Remote Method Invocation (RMI) アプリケーション
JTA の詳細については、Sun Microsystems が発行する次の API Javadoc を参照してください。
javax.transaction および javax.transaction.xa (http://java.sun.com/products/jta/javadocs-1.0.1/index.html
)
Java Transaction API 仕様 (http://www.javasoft.com/products/jta/index.html
)
WebLogic Server では、エンタープライズ アプリケーションの分散トランザクションと 2 フェーズ コミット プロトコルがサポートされます。分散トランザクションとは、複数のリソース マネージャ (データベースなど) が調和的に更新されるトランザクションのことです。一方、ローカル トランザクションは、内部的に API 呼び出しを調整する 1 つのリソース マネージャに対して、トランザクションを開始およびコミットします。このため、トランザクション マネージャはありません。2 フェーズ コミット プロトコルは、複数のリソース マネージャにまたがって 1 つのトランザクションを調整する手段です。これにより、トランザクションによる更新を関連するデータベースのすべてでコミットするか、またはすべてのデータベースから完全にロールバックし、トランザクション開始前の状態に戻すことで、データの整合性が保証されます。つまり、関連するすべてのデータベースが更新されるか、またはどのデータベースも更新されないか、のどちらかだということです。
分散トランザクションには、以下のものが参加します。
トランザクション オリジネータ - トランザクションを開始します。トランザクション オリジネータとしては、ユーザ アプリケーション、エンタープライズ JavaBean、または JMS クライアントがあります。
トランザクション マネージャ - アプリケーション プログラムに代わってトランザクションを管理します。トランザクション マネージャは、トランザクションの開始と完了を行うアプリケーション プログラムからのコマンドを、それらのトランザクションに関わるすべてのリソース マネージャと通信することで調整します。リソース マネージャがトランザクション中に失敗した場合、トランザクション マネージャはリソース マネージャが保留中のトランザクションをコミットするかロールバックするかを決定するのを支援します。
回復可能なリソース - データの永続ストレージを提供します。ほとんどの場合はリソースとしてデータベースが使用されます。
リソース マネージャ - 情報やプロセスへのアクセス手段を提供します。リソース マネージャとしてはトランザクション対応 JDBC ドライバがよく使用されます。リソース マネージャはトランザクションの機能とアクションの永続性を提供します (これらは分散トランザクションの中でアクセスおよび管理されるエンティティ)。リソース マネージャと特定のリソースとの通信は、トランザクション ブランチと呼ばれます。
2 フェーズ コミット プロトコルの最初のフェーズは準備フェーズと呼ばれます。要求された更新がトランザクション ログ ファイルに記録されたら、リソースはリソース マネージャを通じて変更の準備ができていることを示さなければなりません。リソースは、更新をコミットするのか、または前の状態にロールバックするのかを意思表示できます。第 2 フェーズで何が行われるかは、リソースの意思表示によって決まります。すべてのリソースがコミットを支持すると、トランザクションに関わっているすべてのリソースが更新されます。1 つまたは複数のリソースがロールバックを支持した場合は、トランザクションに関わっているすべてのリソースが前の状態にロールバックされます。
WebLogic JTA では、ビジネス トランザクションが以下のようにサポートされています。
クライアント アプリケーションがトランザクションを開始したときにユニークなトランザクション識別子が作成される。
トランザクションが表すビジネス プロセスを説明するトランザクション名 (省略可能) がサポートされる。トランザクション名を使用すると統計やエラー メッセージが、より有意義になります。
トランザクションに関わっており、したがってトランザクションのコミット段階で調整しなければならないオブジェクトを追跡するために WebLogic Server インフラストラクチャが連係して機能する。
トランザクションでアクセスされるときに、リソース マネージャ (たいていはデータベース) が通知を受ける。通知を受けたリソース マネージャは、トランザクションが終了するまでアクセス対象のレコードをロックします。
トランザクションの完了時に 2 フェーズ コミットが調整される。この調整により、トランザクションに関わっているすべてのリソースで更新が同時にコミットされます。コミットの調整は、Open Group の XA プロトコルを使用して更新されるすべてのデータベースで行われます。この規格は、普及している多くのリレーショナル データベースでサポートされています。
トランザクションを停止する必要があるときにロールバック処理が実行される。
障害が起きたときに回復処理が実行される。クラッシュの時点でアクティブだったトランザクションが確認され、そのトランザクションをロールバックするのかコミットするのかが判断されます。
トランザクションのタイムアウトが管理される。ビジネス処理にあまりにも多くの時間がかかる場合、またはビジネス処理が障害のために途中で終了している場合は、トランザクションのタイムアウトが自動的に発行され、データベース ロックなどのリソースが解放されます。
トランザクションは、以下のような状況で使用するのが適しています。各状況は、WebLogic Server システムでサポートされているトランザクション モデルを表現しています。分散トランザクションは、ユーザ入力の複数の画面にまたがってはいけないことに注意してください。もっと複雑でハイレベルなトランザクションは、連続する分散トランザクションで実装する必要があります。
オブジェクトに対する 1 回のクライアント呼び出しで、オブジェクトによりデータベースのデータが複数回にわたって編集される。いずれかの編集が失敗した場合、オブジェクトではすべての編集をロールバックすることが必要となります。この状況では、個々のデータベース編集は必ずしも EJB または RMI の呼び出しではありません。アプレットなどのクライアントでは、JNDI を使用して Transaction
オブジェクトおよび TransactionManager
オブジェクトの参照を取得し、トランザクションを開始することができます。
たとえば、銀行のアプリケーションを考えてください。クライアントでは、出納オブジェクトに対して送金処理を要求します。送金処理においては、出納オブジェクトは銀行のデータベースで以下の呼び出しを行わなければなりません。
1 つの口座で送金メソッドを呼び出す。
別の口座で入金メソッドを呼び出す。
データベースで入金が失敗した場合、アプリケーションでは直前の送金をロールバックすることが必要となります。
クライアント アプリケーションで、サーバ アプリケーションで管理されるオブジェクトとの対話を必要とし、特定のオブジェクト インスタンスに対する複数の呼び出しを行う必要がある。その対話には、以下のような特徴の 1 つまたは複数が備わっています。
データは、連続する各呼び出しの間または後でメモリにキャッシュされるか、データベースに書き込まれる。
データは、対話の終わりにデータベースに書き込まれる。
クライアント アプリケーションでは、各呼び出し間のインメモリ コンテキストを保持するオブジェクトが必要となる。つまり、連続する各呼び出しでは、対話の全体を通してメモリに保持されているデータが使用されます。
対話の最後に、クライアント アプリケーションでは対話の途中または最後に行われたデータベースへの書き込み処理をすべて取り消す機能が必要となる。
ここでは以下について説明します。
図 2-1 は、WebLogic Server EJB アプリケーションにおいてトランザクションがどのように機能するのかを図示したものです。
図 2-1 WebLogic Server EJB アプリケーションでのトランザクションの仕組み
WebLogic Server では、WebLogic Server EJB アプリケーションで以下の 2 種類のトランザクションがサポートされています。
コンテナ管理のトランザクションでは、WebLogic Server EJB コンテナによってトランザクションの境界設定が管理される。EJB デプロイメント記述子のトランザクション属性では、各メソッド呼び出しで WebLogic Server EJB コンテナがどのようにトランザクションを処理するのかが指定されます。デプロイメント記述子の詳細については、『Oracle Fusion Middleware Oracle WebLogic Server エンタープライズ JavaBeans (EJB) プログラマーズ ガイド』の「エンタープライズ JavaBean の実装」を参照してください。
Bean 管理のトランザクションでは、EJB によってトランザクションの境界設定が管理される。EJB は、UserTransaction
オブジェクトに対する明示的なメソッド呼び出しを行って、トランザクションの開始、コミット、およびロールバックを行います。詳細については、『Oracle Fusion Middleware Oracle WebLogic Server API Reference』の「weblogic.transaction.UserTransaction
」を参照してください。
トランザクション イベントのシーケンスは、コンテナ管理のトランザクションと Bean 管理のトランザクションで異なります。
トランザクションがコンテナで管理される EJB アプリケーションの場合、基本的なトランザクションは次のように機能します。
Bean プロバイダまたはアプリケーション アセンブラは、EJB のデプロイメント記述子で、トランザクションの種類 (transaction-type
) としてコンテナ管理の境界設定 (Container
) を指定します。
Bean プロバイダまたはアプリケーション アセンブラは、EJB のデプロイメント記述子で、EJB のデフォルトのトランザクション属性 (trans-attribute
要素) を指定します。トランザクション属性としては、NotSupported
、Required
、Supports
、RequiresNew
、Mandatory
、または Never
を設定します。これらの設定の詳細については、Sun Microsystems が発行している EJB 仕様 2.0 のセクション 17.6.2 を参照してください。
必要に応じて、Bean プロバイダまたはアプリケーション アセンブラは、EJB のデプロイメント記述子で、1 つまたは複数のメソッドの trans-attribute
を指定します。
クライアント アプリケーションによって EJB のメソッドが呼び出されると、EJB コンテナはデプロイメント記述子でそのメソッドの trans-attribute
設定を調べます。メソッドの設定が指定されていない場合は、その EJB のデフォルトの trans-attribute
設定が使用されます。
EJB コンテナは、trans-attribute
の設定に応じて適切に動作します。
たとえば、trans-attribute
の設定が Required
の場合、EJB コンテナは既存のトランザクション コンテキストでメソッドを呼び出す。クライアントがトランザクション コンテキストなしで呼び出しを行った場合、EJB コンテナはメソッドを実行する前に新しいトランザクションを開始します。
trans-attribute
の設定が Mandatory
の場合、EJB コンテナは既存のトランザクション コンテキストでメソッドを呼び出す。クライアントがトランザクション コンテキストなしで呼び出しを行った場合、EJB コンテナは javax.transaction.TransactionRequiredException
例外を送出します。
ビジネス メソッドの呼び出しの途中で、ロールバックが必要だと判断された場合、ビジネス メソッドでは EJBContext.setRollbackOnly
メソッドが呼び出されます。このメソッドでは、メソッド呼び出しの終了時にトランザクションをロールバックしなければならないことが EJB コンテナに通知されます。
注意 : EJBContext.setRollbackOnly メソッドの呼び出しは、意味のあるトランザクション コンテキストを持つメソッドの場合だけ許可されます。 |
メソッドの実行が終了して、その結果がクライアントに送信される前に、EJB コンテナはコミットするかまたはロールバックすることによってトランザクションを完了します。トランザクションがロールバックされるのは、EJBContext.setRollbackOnly
メソッドが呼び出された場合です。
トランザクションの境界設定が Bean で管理される EJB アプリケーションの場合、基本的なトランザクションは次のように機能します。
Bean プロバイダまたはアプリケーション アセンブラは、EJB のデプロイメント記述子で、トランザクションの種類 (transaction-type
) としてコンテナ管理の境界設定 (Bean
) を指定します。
クライアント アプリケーションは、JNDI を使用して、WebLogic Server ドメインの UserTransaction
オブジェクトに対するオブジェクト参照を取得します。
クライアント アプリケーションは、UserTransaction.begin
メソッドを使用してトランザクションを開始し、EJB コンテナを通じて EJB への要求を発行します。EJB でのすべての処理は、トランザクションのスコープ内で実行されます。
いずれかの処理の呼び出しで例外が (明示的に、または通信エラーの結果として) 生成された場合は、その例外を捕捉し、UserTransaction.rollback
メソッドを使用してトランザクションをロールバックできる。
例外が生成されない場合、クライアント アプリケーションは UserTransaction.commit
メソッドを使用して現在のトランザクションをコミットする。このメソッドは、トランザクションを終了して処理を開始します。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。
UserTransaction.commit
メソッドが呼び出されると、EJB コンテナはトランザクションを完了するためにトランザクション マネージャを呼び出します。
トランザクション マネージャの役割は、リソース マネージャと協力してデータベースを更新することです。
図 2-2 は、WebLogic Server RMI アプリケーションでトランザクションがどのように機能するのかを図示したものです。
図 2-2 WebLogic Server RMI アプリケーションでのトランザクションの仕組み
RMI のクライアント アプリケーションとサーバ アプリケーションの場合、基本的なトランザクションは次のように機能します。
アプリケーションは、JNDI を使用して、WebLogic Server ドメインの UserTransaction
オブジェクトに対するオブジェクト参照を返します。
オブジェクト参照を取得すると、アプリケーションとそのオブジェクトが会話状態に入ります。会話状態は、コミットかロールバックによってトランザクションが完了するまで続きます。インスタンス化された RMI オブジェクトは、解放されるまで (たいていはサーバの停止時) メモリ内でアクティブな状態を維持します。トランザクションの間は、WebLogic Server インフラストラクチャによって非アクティベーションやアクティベーションは実行されません。
クライアント アプリケーションは、UserTransaction.begin
メソッドを使用してトランザクションを開始し、サーバ アプリケーションへの要求を発行します。サーバ アプリケーションでのすべての処理は、トランザクションのスコープ内で実行されます。
いずれかの処理の呼び出しで例外が (明示的に、または通信エラーの結果として) 生成された場合は、その例外を捕捉し、UserTransaction.rollback
メソッドを使用してトランザクションをロールバックできる。
例外が生成されない場合、クライアント アプリケーションは UserTransaction.commit
メソッドを使用して現在のトランザクションをコミットする。このメソッドは、トランザクションを終了して処理を開始します。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。
UserTransaction.commit
メソッドが呼び出されると、WebLogic Server はトランザクションを完了するためにトランザクション マネージャを呼び出します。
トランザクション マネージャの役割は、リソース マネージャと協力してデータベースを更新することです。
詳細については、「RMI アプリケーションのトランザクション」を参照してください。
この節の内容は以下のとおりです。
この節では、EJB アプリケーションのクラスから抜粋したサンプル コードを利用して段階的な説明を行います。ここでは以下について説明します。
サンプル コードでは、Bean 管理によるトランザクションの境界設定で UserTransaction
オブジェクトが使用されます。この Bean のデプロイメント記述子では、トランザクションの種類 (transaction-type
要素) として Bean 管理によるトランザクションの境界設定 (Bean
) が指定されます。
注意 : グローバル トランザクションでは、EJB が実行されている WebLogic Server インスタンス上の、ローカル JDBC データ ソースからデータベース接続を使用します。リモート WebLogic Server インスタンス上の JDBC データ ソースからは接続を使用しないでください。以下のサンプル コードは、WebLogic Server に付属するサンプル アプリケーションから抜粋したものではありません。単に、EJB アプリケーションでの |
コード リスト 2-1 は、トランザクションで必要なパッケージのインポートを示しています。必要なパッケージには以下のものがあります。
javax.transaction.UserTransaction
。このオブジェクトに関連付けられているメソッドのリストについては、オンラインの Javadoc を参照してください。
システム例外。例外のリストについては、オンラインの Javadoc を参照してください。
コード リスト 2-1 パッケージのインポート
import javax.naming.*; import javax.transaction.UserTransaction; import javax.transaction.SystemException; import javax.transaction.HeuristicMixedException import javax.transaction.HeuristicRollbackException import javax.transaction.NotSupportedException import javax.transaction.RollbackException import javax.transaction.IllegalStateException import javax.transaction.SecurityException import java.sql.*; import java.util.*;
コード リスト 2-2 に記述されているのは、JNDI ツリー上でオブジェクトをルックアップするためのコードです。
コード リスト 2-2 JNDI ルックアップの実行
Context ctx = null; Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); // WebLogic Server のパラメータ // 環境に合わせて適切なホスト名、ポート番号、 // ユーザ名、およびパスワードに置き換える env.put(Context.PROVIDER_URL, "t3://localhost:7001"); env.put(Context.SECURITY_PRINCIPAL, "Fred"); env.put(Context.SECURITY_CREDENTIALS, "secret"); ctx = new InitialContext(env); UserTransaction tx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction");
コード リスト 2-3 に記述されているのは、UserTransaction
オブジェクトを取得し、javax.transaction.UserTransaction.begin()
メソッドを呼び出すことによって、トランザクションを開始するコードです。このメソッド呼び出しの後、トランザクションが完了するまでに行われるデータベースの処理は、このトランザクションのスコープ内に存在します。
コード リスト 2-4 に記述されているのは、このトランザクションのスコープ内で試行されたいずれかのデータベース処理で例外が送出されたかどうかに応じて、トランザクションを完了するコードです。
いずれかのデータベース処理で例外が送出された場合は、アプリケーションによって javax.transaction.UserTransaction.rollback()
メソッドが呼び出される。
例外が送出されなかった場合は、アプリケーションによって javax.transaction.UserTransaction.commit()
メソッドが呼び出され、すべてのデータベース処理が正常に終了した後にトランザクションのコミットが試行される。このメソッドが呼び出されると、トランザクションが終了し、処理が開始されて、WebLogic Server EJB コンテナによってトランザクションを完了するためにトランザクション マネージャが呼び出されます。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。
この節では、RMI アプリケーションのクラスから抜粋したサンプル コードを利用して段階的な説明を行います。ここでは以下について説明します。
サンプル コードでは、RMI トランザクションで UserTransaction
オブジェクトが使用されます。RMI アプリケーションでトランザクションを使用する際のガイドラインについては、「RMI アプリケーションのトランザクション」を参照してください。
注意 : 以下のサンプル コードは、WebLogic Server に付属するサンプル アプリケーションから抜粋したものではありません。単に、RMI アプリケーションでのUserTransaction オブジェクトの利用を説明するために用意されたものです。 |
コード リスト 2-5 に記述されているのは、必要なパッケージをインポートするコードです。必要なパッケージには、トランザクションの処理に使用する以下のパッケージが含まれます。
javax.transaction.UserTransaction
。このオブジェクトに関連付けられているメソッドのリストについては、オンラインの Javadoc を参照してください。
システム例外。例外のリストについては、オンラインの Javadoc を参照してください。
コード リスト 2-5 パッケージのインポート
import javax.naming.*; import java.rmi.*; import javax.transaction.UserTransaction; import javax.transaction.SystemException; import javax.transaction.HeuristicMixedException import javax.transaction.HeuristicRollbackException import javax.transaction.NotSupportedException import javax.transaction.RollbackException import javax.transaction.IllegalStateException import javax.transaction.SecurityException import java.sql.*; import java.util.*;
これらのクラスがインポートされた後に、UserTransaction
オブジェクトのインスタンスが null に初期化されます。
コード リスト 2-6 に記述されているのは、JNDI ツリーの検索し、適切な WebLogic Server ドメインの UserTransaction
オブジェクトに対するオブジェクト参照を返すためのコードです。
注意 : オブジェクト参照を取得すると、アプリケーションとそのオブジェクトが会話状態に入ります。会話状態は、コミットかロールバックによってトランザクションが完了するまで続きます。インスタンス化された RMI オブジェクトは、解放されるまで (たいていはサーバの停止時) メモリ内でアクティブな状態を維持します。トランザクションの間は、WebLogic Server インフラストラクチャによって非アクティベーションやアクティベーションは実行されません。 |
コード リスト 2-6 JNDI ルックアップの実行
Context ctx = null; Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); // WebLogic Server のパラメータ // 環境に合わせて適切なホスト名、ポート番号、 // ユーザ名、およびパスワードに置き換える env.put(Context.PROVIDER_URL, "t3://localhost:7001"); env.put(Context.SECURITY_PRINCIPAL, "Fred"); env.put(Context.SECURITY_CREDENTIALS, "secret"); ctx = new InitialContext(env); UserTransaction tx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction");
コード リスト 2-7 に記述されているのは、javax.transaction.UserTransaction.begin()
メソッドを呼び出してトランザクションを開始するためのコードです。このメソッド呼び出しの後、トランザクションが完了するまでに行われるデータベースの処理は、このトランザクションのスコープ内に存在します。
コード リスト 2-8 に記述されているのは、このトランザクションのスコープ内で試行されたいずれかのデータベース処理で例外が送出されたかどうかに応じて、トランザクションを完了するコードです。
いずれかのデータベース処理で例外が送出された場合は、アプリケーションによって javax.transaction.UserTransaction.rollback()
メソッドが呼び出される。
例外が送出されなかった場合は、アプリケーションによって javax.transaction.UserTransaction.commit()
メソッドが呼び出され、すべてのデータベース処理が正常に終了した後にトランザクションのコミットが試行される。このメソッドが呼び出されると、トランザクションが終了し、処理が開始されて、WebLogic Server によってトランザクションを完了するためにトランザクション マネージャが呼び出されます。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。