TimesTenでのXA

TimesTen ClassicでのXAの実装によって、『Distributed Transaction Processing: The XA Specification』で指定されているAPIと同じAPIが提供されます。

この項で説明する、TimesTenでのXAの実装を使用する際に必要な前提知識についての内容は次のとおりです。

TimesTenのXA実装の概要および制限事項

TimesTenでのXAインタフェースの実装は、トランザクション・マネージャが分散トランザクション処理(DTP)環境で使用することを目的としています。これらのインタフェースを使用して、TimesTenリソース・マネージャとともに動作するように、新しいトランザクション・マネージャを作成するか、Oracle Tuxedoなどの既存のトランザクション・マネージャを改良できます。

TimesTen XAでは、リソース・マネージャは、TimesTenデータベースで構成するか、またはXAをサポートする他の商用データベースとデータベースを組み合せて構成することができます。

次の重要な制限事項に注意してください。

  • TimesTenのXA実装は、キャッシュと併用できません。キャッシュ・エージェントが実行されている場合、XAトランザクションの開始に失敗します。

  • TimesTenレプリケーションが有効になっている場合、XAトランザクションは実行できません。

  • TimesTenドライバ・マネージャはXAをサポートしていません。

  • DDL文をXAトランザクション内で実行しないでください。

XAのTimesTenデータベース要件

グローバル・トランザクションの一貫性を保証するには、TimesTen XAのトランザクション・ブランチが永続的である必要があります。

xa_prepare()xa_rollback()およびxa_commit()関数のTimesTenの実装では、DurableCommits一般接続属性の設定値またはttDurableCommit組込みプロシージャを使用したかどうかに関係なく、実行された処理をファイル・システムに記録します。(動作はDurableCommits=1を設定した場合と同じです。『Oracle TimesTen In-Memory Databaseリファレンス』DurableCommitsを参照してください。)障害からのリカバリが必要な場合は、リソース・マネージャおよびTimesTenトランザクション・マネージャの両方に、障害発生時にアクティブ(準備された状態)であったトランザクション・ブランチに関する一貫性のあるビューが含まれます。

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

障害発生または予期しない終了の後にデータベースがファイル・システムからロードされてリカバリが行われると、準備されたもののコミットされていないグローバル・トランザクションが保留中(インダウト)の状態のままになります。通常の処理は、すべてのインダウト・トランザクションの処理が解決されるまで有効になりません。

接続およびリカバリが完了すると、TimesTenは、インダウト・トランザクションを確認します。インダウト・トランザクションがない場合、処理は想定どおり続行されます。インダウト・トランザクションがある場合は、他の接続が作成されることもありますが、インダウト・トランザクションが解決されるまで、これらの接続でのすべての処理が事実上禁止されます。他のすべてのODBCまたは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ユーティリティの-HCommitまたは-HAbortオプションを使用して、個々のトランザクション・ブランチを個別にコミットまたはロール・バックできます。ただし、これらのttXactAdminオプションにはADMIN権限が必要であることに注意してください。『Oracle TimesTen In-Memory Databaseリファレンス』ttXactAdminを参照してください。

標準のXA関数をTimesTenで使用する場合の考慮事項

独自のトランザクション・マネージャを作成する場合の、TimesTenでの標準XA関数の使用について、いくつか問題点を示します。

次の項目について説明します。

xa_open()関数

xa_open()で使用されるxa_info文字列は、SQLDriverConnectに指定されたものと同じ接続文字列である必要があります。

"DSN=DataStoreResource;UID=MyName"

XAでは、文字列の長さは256文字に制限されます。xa.hヘッダー・ファイルのMAXINFOSIZEを参照してください。

xa_open()関数は、XA接続をオープンするときに、自動コミットを自動的に無効にします。

xa_open()でオープンされている接続は、xa_close()をコールしてクローズする必要があります。

xa_close()関数

xa_close()で使用されるxa_info文字列は、空である必要があります。

トランザクションID (XID)パラメータ

XAでは、XIDと呼ばれるトランザクションIDを使用してグローバル・トランザクションを一意に識別します。XIDは、トランザクションを処理するXA関数に必要なパラメータです。内部的に、TimesTenはXIDを独自のトランザクション識別子にマップします。

XA標準で定義されたXIDは、long型として定義されたメンバー(formatIDgtrid_lengthbqual_lengthなど)の一部を持ちます。従来、このために、32ビット・クライアント・アプリケーションが64ビット・サーバーに接続されている場合や、64ビット・クライアント・アプリケーションが32ビット・サーバーに接続されている場合には問題が発生することがありました。longは、32ビット・プラットフォームでは32ビット整数で、64ビット・プラットフォームでは64ビット整数であるためです(64ビットWindows以外)。このため、TimesTenは、クライアントまたはサーバーのプラットフォームのタイプに関係なく、これらのXIDメンバーの最小有効32ビットのみを内部的に使用します。TimesTenでは、32ビットの整数に適合しないXIDメンバーの値はサポートされません。

XA接続からODBCハンドルを取得するTimesTen tt_xa_context関数

TimesTenの関数tt_xa_context()を使用すると、xa_open()でオープンされたXA接続に関連付けられているODBC接続ハンドルを取得できます。

tt_xa_contextの構文およびパラメータの説明

tt_xa_context関数の構文は、次のとおりです。

#include <tt_xa.h>
int tt_xa_context(int* rmid, SQLHENV* henv, SQLHDBC* hdbc);

この表では、パラメータを説明します。

パラメータ 説明

rmid

int

指定したリソース・マネージャID

これがNULL以外の場合は、この関数によって、そのrmid値に関連付けられているハンドルが返されます。

指定したrmidがNULLの場合は、この関数によって、このスレッドでの最初の接続に関連付けられているハンドルが返されます。たとえば、ユーザーが記述したコードの範囲外で接続がオープンされている場合に、NULL値を指定します。この場合、rmidは不明です。この設定では、アプリケーション環境でコンテキストが確立されます。

henv

out SQLHENV

現在のxa_open()コンテキストに関連付けられている環境ハンドル

hdbc

out SQLHDBC

現在のxa_open()コンテキストに関連付けられている接続ハンドル

この関数では、次の値が返されます。

0: 成功しました

1: rmidが見つかりません

-1: 無効なパラメータです

tt_xa_contextの使用

この項では、tt_xa_contextの使用方法を説明します。

次の例では、Tuxedoによってxa_open()およびxa_start()が使用され、データベースへの接続がオープンし、トランザクションが開始していると仮定します。さらに接続のODBC処理を続行するために、tt_xa_context()関数を使用して、xa_open()で割り当てられているSQLHENVおよびSQLHDBCハンドルを検出します。

do_insert()
{

    SQLHENV henv;
    SQLHDBC hdbc;
    SQLHSTMT hstmt;

    /* retrieve the handles for the current connection */
    tt_xa_context(NULL, &henv, &hdbc);

    /* now we can do our ODBC programming as usual */
    SQLAllocStmt(hdbc, &hstmt);

    SQLExecDirect(hstmt, "insert into t1 values (1)", SQL_NTS);

    SQLFreeStmt(hstmt, SQL_DROP);
}

TimesTenでのXA接続を介したODBC関数のコールに関する考慮事項

xa_open()でオープンされたXA接続に関連付けられているODBCハンドルを使用してODBC関数をコールする場合には、考慮が必要な要素があります。

これらについて、次の各項で説明します。

自動コミット

処理を簡素化し、矛盾の発生を回避するために、xa_open()は、XA接続をオープンするときに、自動コミットを自動的に無効にします。

その後、ローカル・トランザクション処理の実行中に、自動コミットを有効または無効にする場合がありますが、xa_start()をコールしてグローバル・トランザクション・ブランチでの処理を開始する前には、無効にする必要があります。自動コミットが有効の場合、xa_start()をコールすると次のエラーが返されます。

Error 11030 - "Autocommit must be turned off when working on global (XA) transactions"

xa_start()をコールしてグローバル・トランザクション・ブランチでの処理を開始した後、xa_end()をコールしてその処理を完了するまで、自動コミットを有効にできない場合があります。この場合、自動コミットを有効にしようとすると、前述と同じエラーが発生します。

ローカルでのトランザクションのコミットおよびロールバック

xa_start()をコールしてグローバル・トランザクション・ブランチでの処理を開始した後、SQLTransactを使用してローカルでのコミットまたはロールバックを実行しようとすると、エラーが発生します。

Error 11031 - "Invalid combination of local transaction and global (XA) transaction"

オープンしているカーソルのクローズ

xa_end()をコールしてグローバル・トランザクション・ブランチでの処理を終了する前に、SQLFreeStmtSQL_CLOSEの値とともに使用して、オープンしているすべての文カーソルをクローズする必要があります。

このようにしなかった場合、次のエラーが返されます。

Error 11032 - "XA request failed due to open cursors"

XAリソース・マネージャ・スイッチ

この項では、XAリソース・マネージャ・スイッチについて説明します。

リソース・マネージャ・スイッチについて

各リソース・マネージャは、xa.hヘッダー・ファイルにスイッチを定義し、これよって、トランザクション・マネージャはリソース・マネージャ内のXA関数にアクセスできます。

トランザクション・マネージャでは、XAインタフェース関数を直接コールしません。かわりに、スイッチ表の関数をコールし、スイッチ表はリソース・マネージャ内の該当する関数を指します。これにより、アプリケーションを再コンパイルしなくても、リソース・マネージャを追加および削除できます。

TimesTenでのXAの実装では、XAスイッチxa_switch_tの関数は、TimesTenスイッチtt_xa_switchで定義されているそれぞれの関数を指します。

XAスイッチxa_switch_t

xa_switch_t構造体は、XA仕様によって定義されています。

/* XA Switch Data Structure */
#define RMNAMESZ       32         /* length of resource manager name, */
                                  /* including the null terminator */
#define MAXINFOSIZE    256        /* maximum size in bytes of xa_info strings, */
                                  /* including the null terminator */

struct xa_switch_t
{

    char name[RMNAMESZ];                /* name of resource manager */
    long flags;                         /* resource manager specific options */
    long version;                       /* must be 0 */

int (*xa_open_entry)(char*, int, long);        /* xa_open function pointer */
int (*xa_close_entry)(char*, int, long);       /* xa_close function pointer*/
int (*xa_start_entry)(XID*, int, long);        /* xa_start function pointer */
int (*xa_end_entry)(XID*, int, long);          /* xa_end function pointer */
int (*xa_rollback_entry)(XID*, int, long);     /* xa_rollback function pointer */
int (*xa_prepare_entry)(XID*, int, long);      /* xa_prepare function pointer */
int (*xa_commit_entry)(XID*, int, long);       /* xa_commit function pointer */
int (*xa_recover_entry)(XID*, long, int, long); /* xa_recover function pointer*/
int (*xa_forget_entry)(XID*, int, long);        /* xa_forget function pointer */
int (*xa_complete_entry)(int*, int*, int, long);/* xa_complete function pointer */
};

typedef struct xa_switch_t xa_switch_t;
/*
 * Flag definitions for the RM switch
 */
#define TMNOFLAGS 0x00000000L     /* no resource manager features selected */
#define TMREGISTER 0x00000001L    /* resource manager dynamically registers */
#define TMNOMIGRATE 0x00000002L   /* RM does not support association migration */
#define TMUSEASYNC 0x00000004L    /* RM supports asynchronous operations */

TimesTenスイッチtt_xa_switch

tt_xa_switchでは、TimesTenリソース・マネージャで実装されている実際の関数に名前を付けます。また、関連移行がサポートされていないことを明示的に示します。なお、動的な登録と非同期の処理もサポートされません。

struct xa_switch_t
tt_xa_switch =
{
    "TimesTen", /* name of resource manager */
    TMNOMIGRATE, /* RM does not support association migration */
    0,
    tt_xa_open,
    tt_xa_close,
    tt_xa_start,
    tt_xa_end,
    tt_xa_rollback,
    tt_xa_prepare,
    tt_xa_commit,
    tt_xa_recover,
    tt_xa_forget,
    tt_xa_complete
};

TimesTenでのXAエラー処理

XA仕様では、XAインタフェース・コールから返される可能性がある一定のエラーが厳密に定義されています。ODBC SQLError関数は、XAで定義されたエラーを追加情報ととともに返します。

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

『Oracle TimesTen In-Memory Databaseエラー・メッセージおよびSNMPトラップ』エラーおよび警告を参照してください。