Oracle® Fusion Middleware Oracle WebLogic Server JTAのプログラミング 11g リリース1 (10.3.6) B61631-05 |
|
![]() 前 |
![]() 次 |
この章では、トランザクションの基本的な概要、トランザクションをいつ使用するか、トランザクションが処理される方法、およびサンプル・トランザクション・コードについて説明します。
この節の内容は以下のとおりです。
WebLogic Serverの最も基本的な機能の1つはトランザクション管理です。トランザクションは、データベースの変更を正確に完了させるための手段です。また、トランザクションによって、以下のような高性能トランザクションのすべてのACIDプロパティがデータベース・トランザクションに備わります。
原子性 - トランザクションによるデータベースへの変更はすべて1つの単位として行われ、そうでない場合にはすべての変更がロールバックされます。
一貫性 - トランザクションが正常に実行されると、データベースが前の有効状態から新しい有効状態に変化します。
隔離性 - トランザクションによるデータベースへの変更は、トランザクションが処理を完了するまで他の処理からは見えません。
持続性 - トランザクションによるデータベースへの変更は、システムまたは媒体の障害が発生しても失われません。
WebLogic Serverはデータベースの更新が正確に行われるようにする優れたインフラストラクチャを備えているので、様々なリソース・マネージャにまたがる場合であってもトランザクションの整合性が保護されます。1つの処理でエラーが起きた場合は、関連するすべての処理がロールバックされます。
WebLogic Serverでは、Java Platform, Enterprise Edition (Java EE)プログラミング・モデルのトランザクションがサポートされています。WebLogic Serverは、Enterprise JavaBeans (EJB)仕様3.0に準拠して、Enterprise JavaBeansを使用するJavaアプリケーションにおけるトランザクションを完全にサポートします。また、WebLogic Serverは、Java Transaction API (JTA)仕様1.1もサポートします。どちらの仕様も次の場所で公開されています:
WebLogic Serverでは、Java Transaction API (JTA)がサポートされています。JTAは、以下のアプリケーションで使用されます。
WebLogic Server EJBコンテナ内のEnterprise JavaBean (EJB)アプリケーション
WebLogic Serverインフラストラクチャ内のRemote Method Invocation (RMI)アプリケーション
JTAの詳細は、以下のAPI Javadocを参照してください。
javax.transactionおよびjavax.transaction.xa (http://docs.oracle.com/javaee/5/api/index.html
)
Java Transaction API仕様(http://www.oracle.com/technetwork/java/javaee/jta/index.html
)
WebLogic Serverでは、エンタープライズ・アプリケーションの分散トランザクションと2フェーズ・コミット・プロトコルがサポートされます。分散トランザクションとは、複数のリソース・マネージャ(データベースなど)が調和的に更新されるトランザクションのことです。一方、ローカル・トランザクションは、内部的にAPI呼出しを調整する1つのリソース・マネージャに対して、トランザクションを開始およびコミットします。このため、トランザクション・マネージャはありません。2フェーズ・コミット・プロトコルは、複数のリソース・マネージャにまたがって1つのトランザクションを調整する手段です。これにより、トランザクションによる更新を関連するデータベースのすべてでコミットするか、またはすべてのデータベースから完全にロールバックし、トランザクション開始前の状態に戻すことで、データの整合性が保証されます。つまり、関連するすべてのデータベースが更新されるか、またはどのデータベースも更新されないか、のどちらかだということです。
分散トランザクションには、以下のものが参加します。
トランザクション・オリジネータ - トランザクションを開始します。トランザクション・オリジネータとしては、ユーザー・アプリケーション、Enterprise 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アプリケーションにおいてトランザクションがどのように機能するのかを図示したものです。
WebLogic Serverでは、WebLogic Server EJBアプリケーションで以下の2種類のトランザクションがサポートされています。
コンテナ管理のトランザクションでは、WebLogic Server EJBコンテナによってトランザクションの境界設定が管理されます。EJBデプロイメント記述子のトランザクション属性では、各メソッド呼出しでWebLogic Server EJBコンテナがどのようにトランザクションを処理するのかが指定されます。デプロイメント記述子の詳細は、『Oracle WebLogic Server Enterprise JavaBeansのプログラミング』のEnterprise Java Beansの実装に関する項を参照してください。
Bean管理のトランザクションでは、EJBによってトランザクションの境界設定が管理されます。EJBは、UserTransaction
オブジェクトに対する明示的なメソッド呼出しを行って、トランザクションの開始、コミット、およびロールバックを行います。詳細は、Oracle WebLogic Server APIリファレンスのweblogic.transaction.UserTransaction
を参照してください。
トランザクション・イベントのシーケンスは、コンテナ管理のトランザクションとBean管理のトランザクションで異なります。
トランザクションがコンテナで管理されるEJBアプリケーションの場合、基本的なトランザクションは次のように機能します。
Beanプロバイダまたはアプリケーション・アセンブラは、EJBのデプロイメント記述子で、トランザクションの種類(transaction-type
)としてコンテナ管理の境界設定(Container
)を指定します。
Beanプロバイダまたはアプリケーション・アセンブラは、EJBのデプロイメント記述子で、EJBのデフォルトのトランザクション属性(trans-attribute
要素)を指定します。トランザクション属性としては、NotSupported
、Required
、Supports
、RequiresNew
、Mandatory
、またはNever
を設定します。これらの設定の詳細は、Enterprise JavaBeans仕様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コンテナに通知されます。
注意:
|
メソッドの実行が終了して、その結果がクライアントに送信される前に、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アプリケーションでトランザクションがどのように機能するのかを図示したものです。
RMIのクライアント・アプリケーションとサーバー・アプリケーションの場合、基本的なトランザクションは次のように機能します。
アプリケーションは、JNDIを使用して、WebLogic ServerドメインのUserTransaction
オブジェクトに対するオブジェクト参照を返します。
オブジェクト参照を取得すると、アプリケーションとそのオブジェクトが会話状態に入ります。会話状態は、コミットかロールバックによってトランザクションが完了するまで続きます。インスタンス化されたRMIオブジェクトは、解放されるまで(たいていはサーバーの停止時)メモリー内でアクティブな状態を維持します。トランザクションの間は、WebLogic Serverインフラストラクチャによって非アクティベーションやアクティベーションは実行されません。
クライアント・アプリケーションは、UserTransaction.begin
メソッドを使用してトランザクションを開始し、サーバー・アプリケーションへのリクエストを発行します。サーバー・アプリケーションでのすべての処理は、トランザクションのスコープ内で実行されます。
いずれかの処理の呼出しで例外が(明示的に、または通信エラーの結果として)生成された場合は、その例外を捕捉し、UserTransaction.rollback
メソッドを使用してトランザクションをロールバックできます。
例外が生成されない場合、クライアント・アプリケーションはUserTransaction.commit
メソッドを使用して現在のトランザクションをコミットします。このメソッドは、トランザクションを終了して処理を開始します。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。
UserTransaction.commit
メソッドが呼び出されると、WebLogic Serverはトランザクションを完了するためにトランザクション・マネージャを呼び出します。
トランザクション・マネージャの役割は、リソース・マネージャと協力してデータベースを更新することです。
詳細については、第9章「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"); // Parameters for the WebLogic Server. // Substitute the correct hostname, port number // user name, and password for your environment: 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アプリケーションでトランザクションを使用する際のガイドラインについては、第9章「RMIアプリケーションのトランザクション」を参照してください。
注意: これらのコード・フラグメントは、WebLogic Serverに付属するサンプル・アプリケーションから抜粋したものではありません。単に、RMIアプリケーションでの |
例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"); // Parameters for the WebLogic Server. // Substitute the correct hostname, port number // user name, and password for your environment: 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によってトランザクションを完了するためにトランザクション・マネージャが呼び出されます。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。