ヘッダーをスキップ
Oracle® TimesTen In-Memory Database C開発者ガイド
11gリリース2 (11.2.2)
B66444-05
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

6 分散トランザクション処理: XA

この章では、TimesTenでのX/Open XA標準の実装について説明します。

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

この章では、TimesTenでのXAの実装に固有の情報を示します。また、必要に応じて、次のドキュメントも参照してください。

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


重要:

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

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

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


XAの概要

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

X/Open DTPモデル

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

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

図6-1の説明が続きます。
図6-1「分散トランザクション処理モデル」の説明

TXインタフェースは、アプリケーションがトランザクション・マネージャとの通信に使用するインタフェースです。図は、グローバル・トランザクションをトランザクション・マネージャに送信するアプリケーションを示しています。DTPモデルでは、トランザクション・マネージャが、各グローバル・トランザクションを複数のブランチに分割し、それらを別々のリソース・マネージャに分散して処理します。トランザクション・マネージャは、XAインタフェースを使用して、各トランザクション・ブランチと適切なリソース・マネージャを組み合せます。

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

TXおよびXAインタフェースによって提供されるグローバル・トランザクションの制御は、ネイティブのODBCインタフェースによって提供されるローカル・トランザクションの制御とは異なります。通常は、ローカル・トランザクションとグローバル・トランザクションで別々の接続を維持することをお薦めします。アプリケーションは、TimesTenリソース・マネージャに対する接続ハンドルを取得して、同じ接続上でローカル・トランザクションおよびグローバル・トランザクションの両方を開始できます。詳細は、「XA接続からODBCハンドルを取得するTimesTen tt_xa_context関数」を参照してください。

2フェーズ・コミット

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

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

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

次の最適化に注意してください。

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

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


注意:

トランザクション・マネージャでは、すべてのブランチが正常にコミットされた場合にのみ、グローバル・トランザクションがコミットされたと認識されます。

TimesTenでのXAの使用

TimesTenでのXAの実装によって、『Distributed Transaction Processing: The XA Specification』で指定されているAPIと同じAPIが提供されます。この項で説明する、TimesTenでの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()をコールしてクローズする必要があります。


注意:

TimesTenに接続する、インスタンス管理者以外の任意のユーザーには、CREATE SESSION権限を付与する必要があります。「接続のアクセス制御」を参照してください。

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ビットのWindows以外)では64ビットの整数となるためです。したがって、TimesTenは、クライアントまたはサーバーのプラットフォームのタイプに関係なく、これらのXIDメンバーの最小有効32ビットのみを内部的に使用します。TimesTenでは、32ビットの整数に適合しないXIDメンバーの値はサポートされません。

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

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

構文

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

パラメータ

パラメータ 説明
rmid int 指定したリソース・マネージャID

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

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

henv out SQLHENV 現在のxa_open()コンテキストに関連付けられている環境ハンドル
hdbc out SQLHDBC 現在のxa_open()コンテキストに関連付けられている接続ハンドル

戻り値

0: 成功

1: rmidが見つかりません

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

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

例6-1 tt_xa_context()を使用したハンドルの検出

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関数をコールする際に注意する必要があるTimesTenの問題について、いくつか説明します。

Autocommit

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

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

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

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

ローカル・トランザクションのCOMMITおよびROLLBACK

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

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

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

xa_end()をコールしてグローバル・トランザクション・ブランチでの処理を終了する前に、SQLFreeStmtSQL_CLOSEの値とともに使用して、オープンしているすべての文カーソルをクローズする必要があります。このようにしなかった場合、次のエラーが返されます。

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

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

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

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

xa_switch_t

XA仕様によって定義されているxa_switch_t構造体は次のとおりです。

/* 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 */

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トラップ』の「警告およびエラー」を参照してください。

Windows ODBCドライバ・マネージャを介したXAサポート

この項では、XAをWindows ODBCドライバ・マネージャとともに使用する場合の問題点および手順について説明します。(UNIX ODBCドライバ・マネージャについては対象としていません。)

考慮事項

ODBCドライバ・マネージャを介したXAサポートには特別な処理が必要です。次の2つの基本的な問題があります。

  • XAインタフェースは、定義済のODBCインタフェースには含まれていません。アプリケーションでXA記号が直接参照される場合は、すべての外部参照を解決するために、ドライバ・マネージャ・ライブラリのみとリンクすることはできません。

  • 設計では、SQLConnectまたはSQLDriverConnectをコールすると、接続時にドライバ・マネージャがロードするドライバ.dllファイルを決定します。XAは、xa_open()を介して接続をオープンする必要があることを命令します。ただし、接続処理中に.dllがロードされるまで、適切なxa_open()エントリ・ポイントを指定することはできません。

基本的に各XAの実装は独自のものであるため、通常、データベースの移植性というドライバ・マネージャの目的はここでは適用できないことに注意してください。ドライバ・マネージャでXA対応のアプリケーションをサポートする主な利点は、TimesTen固有のアプリケーションをTimesTenの直接ドライバまたはTimesTenのClient/Serverドライバを使用して透過的に実行できることです。

TimesTen ODBC XAドライバ・マネージャの拡張ライブラリへのリンク

Windowsインストールでは、TimesTenによってXA関数用に、ドライバ・マネージャの拡張ライブラリttxadm1122.dllが提供されます。アプリケーションは、XAを直接コールすることができますが、拡張ライブラリにリンクする必要があります。

ttxadm1122.dllライブラリとリンクするには、リンク行のodbc32.libの前にttxadm1122.libを含める必要があります。次に例を示します。

# Link with the ODBC driver manager
appldm.exe:appl.obj
       $(CC) /Feappldm.exe appl.obj ttxadm1122.lib odbc32.lib

注意:

XAドライバ・マネージャの拡張機能は、32-bitのWindowsアプリケーションでのみ実装されます。

TimesTen XAを使用するためのTuxedoの構成

TimesTenリソース・マネージャを使用するようにTuxedoを構成するには、次のタスクを実行します。


重要:

TimesTen XAはOracle Tuxedoトランザクション・マネージャと連携して動作することが実証されていますが、TimesTenでのXAの実装範囲を超えるDTPソフトウェアの動作は保証されていません。


注意:

  • この項の例では、直接ドライバを使用します。また、クライアント/サーバー・ライブラリまたはドライバ・マネージャ・ライブラリをXA拡張ライブラリとともに使用することもできます。

  • オブジェクトリレーショナル・マッピング・フレームワークおよびアプリケーション・サーバー(Oracle WebLogic Application Serverなど)用にTimesTenを構成する詳細は、TimesTenクイック・スタートを参照してください。「Configuration and Setup」の「Java EE and OR Mapping」をクリックしてください。


$TUXDIR/udataobj/RMファイルの更新

TimesTen XAリソース・マネージャをOracle Tuxedoシステムに統合するには、TimesTenリソース・マネージャ、TimesTenリソース・マネージャ・スイッチの名前(tt_xa_switch)およびリソース・マネージャのライブラリの名前を示すように$TUXDIR/udataobj/RMファイルを更新します。

UNIXプラットフォームで、次の行を追加します。

TimesTen:tt_xa_switch:-Linstall_dir/lib -ltten

次に例を示します。

TimesTen:tt_xa_switch:-L/opt/TimesTen/giraffe/lib -ltten

Windowsプラットフォームで、次の行を追加します。

TimesTen;tt_xa_switch;install_dir\lib\ttdv1122.lib

次に例を示します。

TimesTen;tt_xa_switch;C:\TimesTen\giraffe\lib\ttdv1122.lib

注意:

install_dirは、TimesTenホーム・ディレクトリのパスです。

Tuxedoトランザクション・マネージャ・サーバーの構築

buildtmsコマンドを使用して、TimesTenリソース・マネージャ用のトランザクション・マネージャ・サーバーを構築します。その後、buildtmsで作成したTMS_TTファイルを$TUXDIR/binディレクトリにコピーします。

UNIXプラットフォームでは、コマンドは次のようになります。

buildtms -o TMS_TT -r TimesTen -v
cp TMS_TT $TUXDIR/bin

Windowsプラットフォームでは、コマンドは次のようになります。

buildtms -o TMS_TT -r TimesTen -v
copy TMS_TT.exe %TUXDIR%\bin

UBBCONFIGファイルのGROUPSセクションの更新

TMSNAMEbuildtmsコマンドで作成したTMS_TTファイルを指定します(前述の項を参照)。

TMSNAME=TMS_TT

各TimesTenリソース・マネージャについて、グループ名の後にLMIDGRPNOおよびOPENINFOパラメータが続く行を入力します。OPENINFO文字列は、次のようになります。

OPENINFO="TimesTen:DSN=DSNname"

DSNnameは、データベースの名前です。

Windowsでは、TuxedoサーバーはユーザーSYSTEMとして実行されることに注意してください。OPENINFO文字列にUID一般接続属性を追加して、SYSTEM以外のユーザーを指定します。

OPENINFO="TimesTen:DSN=DSNname;UID=user"

どのTimesTenリソース・マネージャにもCLOSEINFOパラメータを指定しないでください。

例6-2に、GROUP1GROUP2という2つのTimesTenリソース・マネージャの構成に使用するUBBCONFIGファイルの一部を示します。

例6-2 TimesTenリソース・マネージャの構成

*RESOURCES
...
*MACHINES
...
ENGSERV LMID=simple
*GROUPS
DEFAULT: TMSNAME=TMS_TT TMSCOUNT=2
GROUP1
    LMID=simple GRPNO=1 OPENINFO="TimesTen:DSN=MyDSN1;UID=MyName"
GROUP2
    LMID=simple GRPNO=2 OPENINFO="TimesTen:DSN=MyDSN2;UID=MyName"
*SERVERS
DEFAULT:
    CLOPT="-A"
simpserv1 SRVGRP=GROUP1 SRVID=1
simpserv2 SRVGRP=GROUP2 SRVID=2

*SERVICES
TOUPPER
TOLOWER

サーバーのコンパイル

TimesTen includeファイルを含んでいるinstall_dir/includeディレクトリを含むように、CFLAGS環境変数を設定します。その後、buildserverコマンドを使用して、Oracle Tuxedo ATMIサーバー・ロード・モジュールを構成します。

UNIXプラットフォームで、次の行を入力します。

export CFLAGS=-Iinstall_dir/
buildserver -o server -f server.c -r TimesTen -s SERVICE

Windowsプラットフォームで、次の行を入力します。

set CFLAGS=-Iinstall_dir\
buildserver -o server -f server.c -r TimesTen -s SERVICE

注意:

install_dirは、TimesTenホーム・ディレクトリのパスです。

例6-3に、buildclientコマンドを使用してクライアント・モジュール(simpcl)を構成する方法と、buildserverコマンドを使用して前述の例6-2UBBCONFIGファイルに記述されている2つのサーバー・モジュールを構成する方法の例を示します。

例6-3 サーバー・モジュールの構成

set CFLAGS=-IC:\TimesTen\giraffe\
buildclient -o simpcl -f simpcl.c
buildserver -v -t -o simpserv1 -f simpserv1.c -r TimesTen -s TOUPPER
buildserver -v -t -o simpserv2 -f simpserv2.c -r TimesTen -s TOLOWER