ヘッダーをスキップ
Oracle TimesTen In-Memory Database Java開発者ガイド
リリース11.2.1
B56049-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

4 分散トランザクション処理: JTA

ここでは、TimesTenに実装されているJavaトランザクションAPI(JTA)について説明します。

TimesTenに実装されているJava JTAインタフェースは、Javaアプリケーション、アプリケーション・サーバーおよびトランザクション・マネージャを有効化して、分散トランザクション処理(DTP)環境でTimesTenリソース・マネージャを使用することを目的にしています。 TimesTenのこの実装はOracle WebLogic Serverで使用するためにサポートされています。

この章では、TimesTenにおけるJTAの実装に固有の情報を説明します。また、次のドキュメントもあわせて参照してください。

TimesTen JTAは、X/Open XA標準のTimesTen実装の最初の部分であるため、ここでの説明の多くは基本的なXA機能に関することです。 『Oracle TimesTen In-Memory Database C開発者ガイド』のXAの分散トランザクション処理に関する項も参照してください。

この章の内容は次のとおりです。


重要:

  • TimesTen XAの実装は、Oracle In-Memory Database Cache(IMDB Cache)では動作しません。 キャッシュ・エージェントが実行されていると、XAトランザクションの開始に失敗します。

  • レプリケーションが有効化されていると、XAトランザクションは実行できません。

  • XAトランザクション内では、DDL文は実行できません。


JTAの概要

この項では、次のXA概念の概要を簡単に説明します。

X/Open DTPモデル

図4-1 にX/Open DTPモデルによって定義されるインタフェースを示します。

図4-1 分散トランザクション処理モデル

図4-1の説明
「図4-1 分散トランザクション処理モデル」の説明

TXインタフェースとは、トランザクション・マネージャとの通信に使用するアプリケーションです。 この図はグローバル・トランザクションをトランザクション・マネージャに伝達するアプリケーションを示しています。 DTPモデルでは、トランザクション・マネージャは、各グローバル・トランザクションを複数のブランチに分割し、分割したグローバル・トランザクションを別々のリソース・マネージャのサービスに分散させます。 トランザクション・マネージャは、JTAインタフェースを使用して、各トランザクション・ブランチと適切なリソース・マネージャを調整します。

TimesTen JTAのコンテキストでは、リソース・マネージャは、TimesTenデータ・ストアのコレクションの場合と、JTAをサポートする他の商用データベースと組み合せたデータ・ストアのコレクションの場合があります。

TXおよびJTAインタフェースで提供されるグローバル・トランザクション制御は、ネイティブのJDBCインタフェースで提供されるローカル・トランザクション制御とは異なります。 一般に、ローカル・トランザクションおよびグローバル・トランザクションには別々の接続を使用することをお薦めします。 アプリケーションは、TimesTenリソース・マネージャの接続ハンドルを取得し、ローカル・トランザクションおよびグローバル・トランザクションの両方を同じ接続で開始することができます。

2フェーズ・コミット

JTAの実装においてトランザクション・マネージャは、グローバル・トランザクションの分散したブランチを2フェーズ・コミット・プロトコルを使用してコミットします。

  1. 第1フェーズでは、トランザクション・マネージャは各リソース・マネージャに対してコミットを準備するように指示します。これは、グローバル・トランザクションの各ブランチがコミット可能であることを確認し、保証するためです。 リソース・マネージャが各ブランチをコミットできない場合、トランザクション・マネージャは、第2フェーズでトランザクション全体をロールバックします。

  2. 第2フェーズでは、トランザクション・マネージャは各リソース・マネージャにブランチをコミットするように指示しますが、第1フェーズで、コミット不能とレポートされた場合は、グローバル・トランザクションをロールバックするように指示します。

次の最適化された動作に注意してください。

  • グローバル・トランザクションに含まれるブランチが1つのみであるとトランザクション・マネージャが判断すると、第1フェーズはスキップし、第2フェーズでトランザクションをコミットします。

  • グローバル・トランザクション・ブランチが読取り専用で、トランザクション・ログ・レコードが生成されない場合、トランザクション・マネージャは第1フェーズでブランチをコミットし、第2フェーズをスキップします。


注意:

トランザクション・マネージャは、すべてのブランチを正常にコミットしたときにかぎり、グローバル・トランザクションがコミットされたとみなします。

TimesTenでのJTAの使用

この項では、TimesTenでJTAを使用する際の次の考慮事項について説明します。

XAに対するTimesTenデータ・ストアの要件

グローバル・トランザクションの一貫性を保証するには、TimesTen XAのトランザクション・ブランチが永続的である必要があります。 xa_prepare()xa_rollback()およびxa_commit()ファンクションのTimesTen実装では、DurableCommits接続属性の設定値またはttDurableCommit組込みプロシージャを使用したかどうかに関係なく、実行された処理をディスクに記録します。 障害からのリカバリが必要な場合は、リソース・マネージャおよびTimesTenトランザクション・マネージャの両方に、障害発生時に準備された状態でアクティブだったトランザクション・ブランチに関する一貫性のあるビューが含まれています。

トランザクションのロールバックに必要なトランザクション・ロギングは、XAで常に有効にされています。

TimesTenでのグローバル・トランザクションのリカバリ

障害または予期しない終了の後、リカバリのためにTimesTenデータ・ストアがディスクからロードされたとき、準備されたが、コミットされていないすべてのグローバル・トランザクションは保留中(インダウト)の状態のままです。 すべてのインダウト・トランザクションが解決されるまで、通常の処理は行えません。

接続およびリカバリが完了すると、TimesTenはインダウト・トランザクションを確認します。 インダウト・トランザクションがない場合は、処理を通常どおり実行します。 インダウト・トランザクションがあると、他の接続を作成することはできますが、インダウト・トランザクションが解決されるまでは、これらの接続でのすべての処理が事実上禁止されます。 他のすべてのJDBCのコールは次のエラーになります。

Error 11035 - "In-doubt transactions awaiting resolution in recovery must be resolved first"

インダウト・トランザクションのリストは、xa_recover()のXA実装によって取得した後、XAでxa_commit()xa_rollback()またはxa_forget()を適切にコールすることによって処理できます。 すべてのインダウト・トランザクションが解消されると、処理が通常通り続行されます。

トランザクション・マネージャでは、接続後にまずxa_recover()をコールする必要があるため、この方法はトランザクション・マネージャで厳密に制御された状態で動作するシステムに適しています。

トランザクション・マネージャを使用できない場合またはインダウト・トランザクションを解消できない場合は、ttXactAdminユーティリティを使用して、個々のトランザクション・ブランチを個別にコミットするか、または強制終了します。 ただし、このようなttXactAdminによる方法では、ADMIN権限が必要なことに注意してください。 『Oracle TimesTen In-Memory Databaseリファレンス』のttXactAdminに関する項を参照してください。

TimesTenでのXAエラーの処理

XA仕様では、XAインタフェース・コールから返される可能性がある一定のエラーが厳密に定義されています。 ODBCのSQLErrorメカニズムは、他の補足情報(ある場合)とともにXAの定義済エラーを返します。

TimesTenのXA関連エラーは、11000番から始まります。エラー11002から11020は、XA標準で定義済のエラーに対応しています。

すべてのエラーの一覧は、『Oracle TimesTen In-Memory Databaseエラー・メッセージおよびSNMPトラップ』の警告とエラーに関する章を参照してください。

JTA APIの使用

TimesTenのJTA実装は、Sun Microsystems社のJTA仕様の規定に準拠したAPIを提供します。 TimesTenのJTAはJDK 1.4以上のバージョンで動作します。

この項では、JTA APIの使用に関する次の内容について説明します。


注意:

WebLogicでTimesTen DSNを登録する方法、TimesTenのアプリケーション・サーバーの構成およびオブジェクトリレーショナル・マッピングのフレームワークに関する情報については、次のURLで参照可能です。

http://www.oracle.com/technology/products/timesten/index.html


必要なパッケージ

TimesTen JDBCおよびXA実装は、次のパッケージから利用可能です。

com.timesten.jdbc.*;
com.timesten.jdbc.xa.*;

アプリケーションは、次の標準パッケージもインポートする必要があります。

import java.sql.*;
import javax.sql.*;
import javax.transaction.xa.*;

TimesTen XAConnectionオブジェクトの作成

XAデータ・ソースへの接続は、XADataSourceオブジェクトを経由して確立されます。 TimesTenXADataSourceインスタンスを接続ファクトリとして使用して、TimesTenデータ・ストアに新しいXAConnectionオブジェクトを作成できます。 TimesTenXADataSourcejavax.sql.XADataSourceインタフェースを実装します。

TimesTenXADataSourceインスタンスを新規に作成したら、setUrl()メソッドを使用して、TimesTenデータ・ストアを指定します。 URLは次のようになります。

  • 直接接続の場合:

    jdbc:timesten:direct:DSNname
    
  • クライアント接続の場合:

    jdbc:timesten:client:DSNname
    

setUser()メソッドおよびsetPassword()メソッドを任意で使用して、特定のユーザーのIDおよびパスワードを設定することもできます。


注意:

TimesTenデータ・ストアに接続するには、権限が付与されている必要があります。 「接続のアクセス制御」を参照してください。

例4-1 TimesTen XAデータ・ソース・オブジェクトの作成

この例では、TimesTenXADataSourceオブジェクトをファクトリとして使用して、新しいTimesTen XAデータ・ソース・オブジェクトを作成します。 次に、このTimesTenXADataSourceインスタンスに、TimesTen DSN(dsn1)、ユーザー名(myName)およびパスワード(myPasswd)を識別するURLが設定されます。 次に、getXAConnection()メソッドが、xaConnという名前のオブジェクトへ接続を返すために使用されます。

TimesTenXADataSource xads = new TimesTenXADataSource();

xads.setUrl("jdbc:timesten:direct:dsn1");
xads.setUser("myName");
xads.setPassword("myPassword");

XAConnection xaConn = null;
try {
    xaConn = xads.getXAConnection();
}
catch (SQLException e){
    e.printStackTrace();
    return;
}

XAデータ・ソース・オブジェクトに対して複数の接続を作成できます。 この例では、xaConn2という名前で2つ目の接続を作成します。

XAConnection xaConn  = null;
XAConnection xaConn2 = null;
try {
    xaConn  = xads.getXAConnection();
    xaConn2 = xads.getXAConnection();
}

例4-2 複数のTimesTen XAデータ・ソース・オブジェクトの作成

この例では、TimesTenXADataSourceの2つのインスタンスを、dsn1およびdsn2という名前のTimesTenデータ・ストアに作成します。 次に、dsn1に1つの接続を作成し、dsn2に2つの接続を作成します。

TimesTenXADataSource xads = new TimesTenXADataSource();

xads.setUrl("jdbc:timesten:direct:dsn1");
xads.setUser("myName");
xads.setPassword("myPassword");

XAConnection xaConn1 = null;
XAConnection xaConn2 = null;
XAConnection xaConn3 = null;

try {
   xaConn1 = xads.getXAConnection(); // connect to dsn1
}
catch (SQLException e){
   e.printStackTrace();
   return;
}

xads.setUrl("jdbc:timesten:direct:dsn2");
xads.setUser("myName");
xads.setPassword("myPassword");

try {
   xaConn2 = xads.getXAConnection(); // connect to dsn2
   xaConn3 = xads.getXAConnection(); // connect to dsn2
}
catch (SQLException e){
   e.printStackTrace();
   return;
}

注意:

XAConnectionが確立されると、自動コミットはオフになります。

XAResourceおよびConnectionオブジェクトの作成

getXAConnection()を使用して、XAConnectionオブジェクトを取得した後、XAConnectionメソッドgetXAResource()を使用して、XAResourceオブジェクトを取得して、次にXAConnectionメソッドgetConnection()を使用して、基礎となる接続のConnectionオブジェクトを取得できます。

例4-3 XAリソース・オブジェクトおよび接続の取得

//get an XAResource
XAResource xaRes = null;
try {
   xaRes = xaConn.getXAResource();
}catch (SQLException e){
   e.printStackTrace();
   return;
}

//get an underlying physical Connection
Connection conn = null;
try {
   conn = xaConn.getConnection();
}catch (SQLException e){
   e.printStackTrace();
   return;
}

この時点で、同一の接続のconnを、ローカル・トランザクションおよびグローバル・トランザクションの両方に使用できます。 ただし、次の点に注意してください。

  • グローバル・トランザクションを開始する前に、アクティブなローカル・トランザクションをコミットまたはロールバックする必要があります。 そうしないと、XAException例外XAER_OUTSIDEが発生します。

  • ローカル・トランザクションを初期化する前に、アクティブなグローバル・トランザクションを終了する必要があります。そうしないと、SQLException、「Illegal combination of local transaction and global (XA) transaction.」が表示されます。