ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Server JTA プログラマーズ ガイド
11g リリース 1 (10.3.1)
B55540-01
 

目次
目次

戻る
戻る
 
次へ
次へ
 

2 トランザクションについて

この章では次の内容について説明します。

WebLogic Server アプリケーションのトランザクションの概要

この節の内容は以下のとおりです。

トランザクションの ACID プロパティ

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 からアクセスできます。

サポートされている API モデル

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 を参照してください。

分散トランザクションと 2 フェーズ コミット プロトコル

WebLogic Server では、エンタープライズ アプリケーションの分散トランザクションと 2 フェーズ コミット プロトコルがサポートされます。分散トランザクションとは、複数のリソース マネージャ (データベースなど) が調和的に更新されるトランザクションのことです。一方、ローカル トランザクションは、内部的に API 呼び出しを調整する 1 つのリソース マネージャに対して、トランザクションを開始およびコミットします。このため、トランザクション マネージャはありません。2 フェーズ コミット プロトコルは、複数のリソース マネージャにまたがって 1 つのトランザクションを調整する手段です。これにより、トランザクションによる更新を関連するデータベースのすべてでコミットするか、またはすべてのデータベースから完全にロールバックし、トランザクション開始前の状態に戻すことで、データの整合性が保証されます。つまり、関連するすべてのデータベースが更新されるか、またはどのデータベースも更新されないか、のどちらかだということです。

分散トランザクションには、以下のものが参加します。

  • トランザクション オリジネータ - トランザクションを開始します。トランザクション オリジネータとしては、ユーザ アプリケーション、エンタープライズ JavaBean、または JMS クライアントがあります。

  • トランザクション マネージャ - アプリケーション プログラムに代わってトランザクションを管理します。トランザクション マネージャは、トランザクションの開始と完了を行うアプリケーション プログラムからのコマンドを、それらのトランザクションに関わるすべてのリソース マネージャと通信することで調整します。リソース マネージャがトランザクション中に失敗した場合、トランザクション マネージャはリソース マネージャが保留中のトランザクションをコミットするかロールバックするかを決定するのを支援します。

  • 回復可能なリソース - データの永続ストレージを提供します。ほとんどの場合はリソースとしてデータベースが使用されます。

  • リソース マネージャ - 情報やプロセスへのアクセス手段を提供します。リソース マネージャとしてはトランザクション対応 JDBC ドライバがよく使用されます。リソース マネージャはトランザクションの機能とアクションの永続性を提供します (これらは分散トランザクションの中でアクセスおよび管理されるエンティティ)。リソース マネージャと特定のリソースとの通信は、トランザクション ブランチと呼ばれます。

2 フェーズ コミット プロトコルの最初のフェーズは準備フェーズと呼ばれます。要求された更新がトランザクション ログ ファイルに記録されたら、リソースはリソース マネージャを通じて変更の準備ができていることを示さなければなりません。リソースは、更新をコミットするのか、または前の状態にロールバックするのかを意思表示できます。第 2 フェーズで何が行われるかは、リソースの意思表示によって決まります。すべてのリソースがコミットを支持すると、トランザクションに関わっているすべてのリソースが更新されます。1 つまたは複数のリソースがロールバックを支持した場合は、トランザクションに関わっているすべてのリソースが前の状態にロールバックされます。

ビジネス トランザクションのサポート

WebLogic JTA では、ビジネス トランザクションが以下のようにサポートされています。

  • クライアント アプリケーションがトランザクションを開始したときにユニークなトランザクション識別子が作成される。

  • トランザクションが表すビジネス プロセスを説明するトランザクション名 (省略可能) がサポートされる。トランザクション名を使用すると統計やエラー メッセージが、より有意義になります。

  • トランザクションに関わっており、したがってトランザクションのコミット段階で調整しなければならないオブジェクトを追跡するために WebLogic Server インフラストラクチャが連係して機能する。

  • トランザクションでアクセスされるときに、リソース マネージャ (たいていはデータベース) が通知を受ける。通知を受けたリソース マネージャは、トランザクションが終了するまでアクセス対象のレコードをロックします。

  • トランザクションの完了時に 2 フェーズ コミットが調整される。この調整により、トランザクションに関わっているすべてのリソースで更新が同時にコミットされます。コミットの調整は、Open Group の XA プロトコルを使用して更新されるすべてのデータベースで行われます。この規格は、普及している多くのリレーショナル データベースでサポートされています。

  • トランザクションを停止する必要があるときにロールバック処理が実行される。

  • 障害が起きたときに回復処理が実行される。クラッシュの時点でアクティブだったトランザクションが確認され、そのトランザクションをロールバックするのかコミットするのかが判断されます。

  • トランザクションのタイムアウトが管理される。ビジネス処理にあまりにも多くの時間がかかる場合、またはビジネス処理が障害のために途中で終了している場合は、トランザクションのタイムアウトが自動的に発行され、データベース ロックなどのリソースが解放されます。

どのような状況で使用するのか

トランザクションは、以下のような状況で使用するのが適しています。各状況は、WebLogic Server システムでサポートされているトランザクション モデルを表現しています。分散トランザクションは、ユーザ入力の複数の画面にまたがってはいけないことに注意してください。もっと複雑でハイレベルなトランザクションは、連続する分散トランザクションで実装する必要があります。

トランザクションの仕組み

ここでは以下について説明します。

WebLogic Server EJB アプリケーションのトランザクション

図 2-1 は、WebLogic Server EJB アプリケーションにおいてトランザクションがどのように機能するのかを図示したものです。

図 2-1 WebLogic Server EJB アプリケーションでのトランザクションの仕組み

図 2-1 の説明については以下を参照
「図 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 アプリケーションの場合、基本的なトランザクションは次のように機能します。

  1. Bean プロバイダまたはアプリケーション アセンブラは、EJB のデプロイメント記述子で、トランザクションの種類 (transaction-type) としてコンテナ管理の境界設定 (Container) を指定します。

  2. Bean プロバイダまたはアプリケーション アセンブラは、EJB のデプロイメント記述子で、EJB のデフォルトのトランザクション属性 (trans-attribute 要素) を指定します。トランザクション属性としては、NotSupportedRequiredSupportsRequiresNewMandatory、または Never を設定します。これらの設定の詳細については、Sun Microsystems が発行している EJB 仕様 2.0 のセクション 17.6.2 を参照してください。

  3. 必要に応じて、Bean プロバイダまたはアプリケーション アセンブラは、EJB のデプロイメント記述子で、1 つまたは複数のメソッドの trans-attribute を指定します。

  4. クライアント アプリケーションによって EJB のメソッドが呼び出されると、EJB コンテナはデプロイメント記述子でそのメソッドの trans-attribute 設定を調べます。メソッドの設定が指定されていない場合は、その EJB のデフォルトの trans-attribute 設定が使用されます。

  5. EJB コンテナは、trans-attribute の設定に応じて適切に動作します。

    • たとえば、trans-attribute の設定が Required の場合、EJB コンテナは既存のトランザクション コンテキストでメソッドを呼び出す。クライアントがトランザクション コンテキストなしで呼び出しを行った場合、EJB コンテナはメソッドを実行する前に新しいトランザクションを開始します。

    • trans-attribute の設定が Mandatory の場合、EJB コンテナは既存のトランザクション コンテキストでメソッドを呼び出す。クライアントがトランザクション コンテキストなしで呼び出しを行った場合、EJB コンテナは javax.transaction.TransactionRequiredException 例外を送出します。

  6. ビジネス メソッドの呼び出しの途中で、ロールバックが必要だと判断された場合、ビジネス メソッドでは EJBContext.setRollbackOnly メソッドが呼び出されます。このメソッドでは、メソッド呼び出しの終了時にトランザクションをロールバックしなければならないことが EJB コンテナに通知されます。


    注意 :

    EJBContext.setRollbackOnly メソッドの呼び出しは、意味のあるトランザクション コンテキストを持つメソッドの場合だけ許可されます。

  7. メソッドの実行が終了して、その結果がクライアントに送信される前に、EJB コンテナはコミットするかまたはロールバックすることによってトランザクションを完了します。トランザクションがロールバックされるのは、EJBContext.setRollbackOnly メソッドが呼び出された場合です。

Bean 管理のトランザクション

トランザクションの境界設定が Bean で管理される EJB アプリケーションの場合、基本的なトランザクションは次のように機能します。

  1. Bean プロバイダまたはアプリケーション アセンブラは、EJB のデプロイメント記述子で、トランザクションの種類 (transaction-type) としてコンテナ管理の境界設定 (Bean) を指定します。

  2. クライアント アプリケーションは、JNDI を使用して、WebLogic Server ドメインの UserTransaction オブジェクトに対するオブジェクト参照を取得します。

  3. クライアント アプリケーションは、UserTransaction.begin メソッドを使用してトランザクションを開始し、EJB コンテナを通じて EJB への要求を発行します。EJB でのすべての処理は、トランザクションのスコープ内で実行されます。

    • いずれかの処理の呼び出しで例外が (明示的に、または通信エラーの結果として) 生成された場合は、その例外を捕捉し、UserTransaction.rollback メソッドを使用してトランザクションをロールバックできる。

    • 例外が生成されない場合、クライアント アプリケーションは UserTransaction.commit メソッドを使用して現在のトランザクションをコミットする。このメソッドは、トランザクションを終了して処理を開始します。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。

  4. UserTransaction.commit メソッドが呼び出されると、EJB コンテナはトランザクションを完了するためにトランザクション マネージャを呼び出します。

  5. トランザクション マネージャの役割は、リソース マネージャと協力してデータベースを更新することです。

WebLogic Server RMI アプリケーションのトランザクション

図 2-2 は、WebLogic Server RMI アプリケーションでトランザクションがどのように機能するのかを図示したものです。

図 2-2 WebLogic Server RMI アプリケーションでのトランザクションの仕組み

図 2-2 の説明については以下を参照
「図 2-2 WebLogic Server RMI アプリケーションでのトランザクションの仕組み」の説明

RMI のクライアント アプリケーションとサーバ アプリケーションの場合、基本的なトランザクションは次のように機能します。

  1. アプリケーションは、JNDI を使用して、WebLogic Server ドメインの UserTransaction オブジェクトに対するオブジェクト参照を返します。

    オブジェクト参照を取得すると、アプリケーションとそのオブジェクトが会話状態に入ります。会話状態は、コミットかロールバックによってトランザクションが完了するまで続きます。インスタンス化された RMI オブジェクトは、解放されるまで (たいていはサーバの停止時) メモリ内でアクティブな状態を維持します。トランザクションの間は、WebLogic Server インフラストラクチャによって非アクティベーションやアクティベーションは実行されません。

  2. クライアント アプリケーションは、UserTransaction.begin メソッドを使用してトランザクションを開始し、サーバ アプリケーションへの要求を発行します。サーバ アプリケーションでのすべての処理は、トランザクションのスコープ内で実行されます。

    • いずれかの処理の呼び出しで例外が (明示的に、または通信エラーの結果として) 生成された場合は、その例外を捕捉し、UserTransaction.rollback メソッドを使用してトランザクションをロールバックできる。

    • 例外が生成されない場合、クライアント アプリケーションは UserTransaction.commit メソッドを使用して現在のトランザクションをコミットする。このメソッドは、トランザクションを終了して処理を開始します。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。

  3. UserTransaction.commit メソッドが呼び出されると、WebLogic Server はトランザクションを完了するためにトランザクション マネージャを呼び出します。

  4. トランザクション マネージャの役割は、リソース マネージャと協力してデータベースを更新することです。

詳細については、「RMI アプリケーションのトランザクション」を参照してください。

トランザクションのサンプル コード

この節の内容は以下のとおりです。

トランザクションのサンプル EJB コード

この節では、EJB アプリケーションのクラスから抜粋したサンプル コードを利用して段階的な説明を行います。ここでは以下について説明します。

サンプル コードでは、Bean 管理によるトランザクションの境界設定で UserTransaction オブジェクトが使用されます。この Bean のデプロイメント記述子では、トランザクションの種類 (transaction-type 要素) として Bean 管理によるトランザクションの境界設定 (Bean) が指定されます。


注意 :

グローバル トランザクションでは、EJB が実行されている WebLogic Server インスタンス上の、ローカル JDBC データ ソースからデータベース接続を使用します。リモート WebLogic Server インスタンス上の JDBC データ ソースからは接続を使用しないでください。

以下のサンプル コードは、WebLogic Server に付属するサンプル アプリケーションから抜粋したものではありません。単に、EJB アプリケーションでの UserTransaction オブジェクトの利用を説明するために用意されたものです。


パッケージをインポートする

コード リスト 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.*;

JNDI を使用してオブジェクト参照を返す

コード リスト 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-3 トランザクションの開始

UserTransaction tx = (UserTransaction)
  ctx.lookup("javax.transaction.UserTransaction");
tx.begin();

トランザクションを完了する

コード リスト 2-4 に記述されているのは、このトランザクションのスコープ内で試行されたいずれかのデータベース処理で例外が送出されたかどうかに応じて、トランザクションを完了するコードです。

  • いずれかのデータベース処理で例外が送出された場合は、アプリケーションによって javax.transaction.UserTransaction.rollback() メソッドが呼び出される。

  • 例外が送出されなかった場合は、アプリケーションによって javax.transaction.UserTransaction.commit() メソッドが呼び出され、すべてのデータベース処理が正常に終了した後にトランザクションのコミットが試行される。このメソッドが呼び出されると、トランザクションが終了し、処理が開始されて、WebLogic Server EJB コンテナによってトランザクションを完了するためにトランザクション マネージャが呼び出されます。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。

コード リスト 2-4 トランザクションの完了

tx.commit();
 
// または
 
tx.rollback();

トランザクションのサンプル RMI コード

この節では、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 に初期化されます。

JNDI を使用して UserTransaction オブジェクトへのオブジェクト参照を返す

コード リスト 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-7 トランザクションの開始

UserTransaction tx = (UserTransaction)
  ctx.lookup("javax.transaction.UserTransaction");
tx.begin();

トランザクションを完了する

コード リスト 2-8 に記述されているのは、このトランザクションのスコープ内で試行されたいずれかのデータベース処理で例外が送出されたかどうかに応じて、トランザクションを完了するコードです。

  • いずれかのデータベース処理で例外が送出された場合は、アプリケーションによって javax.transaction.UserTransaction.rollback() メソッドが呼び出される。

  • 例外が送出されなかった場合は、アプリケーションによって javax.transaction.UserTransaction.commit() メソッドが呼び出され、すべてのデータベース処理が正常に終了した後にトランザクションのコミットが試行される。このメソッドが呼び出されると、トランザクションが終了し、処理が開始されて、WebLogic Server によってトランザクションを完了するためにトランザクション マネージャが呼び出されます。トランザクションは、そのトランザクションに関わっているすべてのリソースがコミットに同意した場合だけコミットされます。

コード リスト 2-8 トランザクションの完了

tx.commit();
 
// または
 
tx.rollback();