注意: 次の理由により、可能であればXAは使用しないでください。
不可避と思われる(たとえば、OracleとOracle以外のリソースを同一トランザクションで使用する必要がある)場合でも、XAの使用を回避できることがあります。 |
この章では、Oracle XAライブラリの使用方法について説明します。通常、このライブラリはトランザクション・モニターで作業するアプリケーションで使用します。XAの機能は、トランザクションが複数のデータベースと相互処理するアプリケーションで最も効果的です。
内容は次のとおりです。
参照:
|
X/Open Distributed Transaction Processing(DTP)アーキテクチャは、複数のアプリケーション・プログラム(AP)が複数の異なるリソース・マネージャ(RM)から提供されるリソースを共有できるようにするための、標準のアーキテクチャまたはインタフェースを定義しています。APとRM間の作業を調整し、グローバル・トランザクションを実現します。
Oracle XAライブラリは、X/Openソフトウェア・アーキテクチャのXAインタフェース仕様に準拠しています。Oracle XAライブラリは外部インタフェースであり、Oracleのクライアント側トランザクション・マネージャ(TM)以外のクライアント側TMがグローバル・トランザクションを調整可能にすることで分散トランザクションにOracle Database以外のRMを組み込めるようにします。たとえば、クライアント・アプリケーションでは、Oracle DatabaseトランザクションとNTFSファイル・システム内のトランザクションを1つのグローバル・トランザクションとして管理できます。
図19-1に、X/Open DTPモデルの例を示します。
内容は次のとおりです。
リソース・マネージャ(RM)
リソース・マネージャは、障害発生後に通常の状態に戻すことができる共有かつリカバリ可能なリソースを制御します。たとえば、リレーショナル・データベース、トランザクション・キューおよびトランザクション・ファイル・システムなどです。Oracle DatabaseはRMであり、障害発生後にREDOログおよびロールバック・セグメントを使用して一貫性のある状態に復帰します。
分散トランザクション
分散トランザクションは、複数の分散リソースに対する更新を伴い、分散RM間で「すべてまたはなし」のセマンティクスを必要とするクライアント・トランザクションであり、グローバル・トランザクションとも呼ばれます。
ブランチ
ブランチは、1つのRMに含まれる1つの作業単位です。複数のブランチが1つのグローバル・トランザクションを構成します。Oracle Databaseの場合、各ブランチはデータベース・サーバー内のローカル・トランザクションにマップします。
トランザクション・マネージャ(TM)
トランザクション・マネージャは、トランザクション境界を指定するためのAPIを提供し、コミットおよびリカバリを管理します。TMでは、分散RM間で「すべてまたはなし」のセマンティクスを提供する2フェーズ・コミット・エンジンが実装されます。
外部TMとは、Oracle Databaseの外部に常駐する中間層コンポーネントです。通常、データベースには固有の内部TMがあります。業界標準に準拠したTMを使用することで、Oracle Databaseは単一のトランザクション内で他の異機種間RMと共存できます。
トランザクション処理モニター(TPM)
TMは、通常、次のようなトランザクション処理モニター(TPM)が提供します。
TPMは、トランザクション要求を発行するクライアント・プロセスとその要求を処理するバックエンド・サーバー間の要求フローを調整します。TPMは、基本的にネットワーク上に分散されているアプリケーション・サーバーやRMなどのように、様々な種類のバックエンド・プロセスに対してサービスを要求するトランザクションを調整します。
TPMは、分散トランザクションを完了するために必要なコミットまたはロールバックを同期化します。TPMのTM部分が、分散コミットおよび分散ロールバックの発生するタイミングを制御します。このため、分散APでTPMを利用する場合、TPMのTM部分が2フェーズ・コミット・プロトコルを制御します。RMを使用して、TMはこのタスクを実行します。
TMは分散コミットまたはロールバックを制御するため、XAインタフェースを介してOracle Database(または他のRM)と直接通信する必要があります。TMは、トランザクション内のすべてのRMに関する情報に基づいて、「Oracle XAライブラリ・サブプログラム」で説明するOracle XAライブラリ・サブプログラムを使用してOracle Databaseにトランザクションの処理方法を指示します。
2フェーズ・コミット・プロトコル
Oracle XAライブラリ・インタフェースは、2フェーズ・コミット・プロトコルに従います。各イベントの順序は次のとおりです。
準備フェーズでは、TMは各RMに対して、トランザクションの任意の部分をコミットできるように要求します。これが可能な場合は、RMは準備ができた状態を記録し、TMに肯定的に応答します。可能でない場合は、RMはすべての作業をロールバックし、TMに否定的に応答し、そのトランザクションに関する情報を消去します。プロトコルによって、アプリケーションまたはRMは、準備フェーズが完了する前にトランザクションを一方的にロールバックできます。
フェーズ2では、TMはコミット決定を記録し、トランザクションに参加しているすべてのRMに対してコミットまたはロールバックを発行します。TMは、すべてのRMがフェーズ1に対して肯定的に応答した場合にのみ、RMのコミットを発行できます。
アプリケーション・プログラム(AP)
アプリケーション・プログラムは、トランザクション境界を定義し、トランザクションを構成するアクションを指定します。たとえば、APはプリコンパイラでもOracle Call Interface(OCI)プログラムでもかまいません。APは、RMのネイティブ・インタフェース(たとえばSQL)を使用して、RMのリソースを操作します。
TXインタフェース
アプリケーション・プログラムは、TMを介し、TXと呼ばれるインタフェースを使用してすべてのトランザクション制御操作を開始および完了します。APがXAインタフェースを直接使用することはありません。APが中間層で分岐するブランチを認識することはありません。アプリケーション・スレッドがブランチの作業を明示的に結合、休止、一時停止および再開するかわりに、トランザクション処理モニターのTM部分がAPのためにグローバル・トランザクションのブランチを管理します。最終的に、APはTMをコールしてすべてをコミットするか、または何もコミットしません。
注意: TXインタフェースおよびその関連のサブプログラムのネーミング規則はベンダー固有です。たとえば、tx_open コールは、使用中のシステムではtp_open と呼ばれている場合があります。また、トランザクションRPCへの入力時など、このコールが暗黙的な場合もあります。詳細は、トランザクション処理モニターに付属のマニュアルを参照してください。 |
密結合と疎結合
RMですべての分離セマンティクスについて単一エンティティとみなされるアプリケーション・スレッドは、密結合となります。密結合ブランチは、相互の変更を認識する必要があります。さらに、外部クライアントは、密結合セットの変更をすべて認識するか、まったく認識しない必要があります。アプリケーション・スレッドが密結合されていない場合は、疎結合となります。
動的登録と静的登録
Oracle Databaseは、動的登録と静的登録の両方をサポートします。動的登録の場合、RMは最初にアプリケーション・コールバックを実行します。静的登録の場合、関係のないRMがあっても、最初に、各RMに対してxa_start
をコールする必要があります。
Oracle Databaseは、リソース・マネージャとして、表19-1に示す情報を発行する必要があります。
表19-1 Oracle Databaseが発行する必要のあるXA機能
XA機能 | Oracle Databaseの詳細 |
---|---|
|
Oracle Databaseの |
|
|
クローズ文字列 |
|
オープン文字列 |
|
ライブラリ |
Oracle XAを使用するアプリケーションをリンクするために必要なライブラリには、プラットフォーム固有の名前が付けられています。TPM固有のライブラリをリンクする必要があることを除けば、通常のプリコンパイラまたはOCIプログラムをリンクする手順と同じです。
|
要件 |
ありません。XAをサポートする機能はStandard EditionおよびEnterprise Editionに含まれています。 |
Oracle XAライブラリ・サブプログラムを使用することで、TMはトランザクションの処理方法をOracle Databaseに指示できます。一般に、TMはxa_open
を使用してリソースをオープンする必要があります。通常、リソースはAPでtx_open
をコールした結果としてオープンされます。一部のTMでは、アプリケーションが開始したときに、暗黙的にxa_open
をコールします。
同様に、アプリケーションがリソースの使用を完了したときに発生するクローズがあります(xa_close
を使用)。このクローズが発生するのは、APがtx_close
をコールしたとき、またはアプリケーションが終了したときです。
TMはRMに対して、次のように他の複数のタスクを実行するように指示します。
トランザクションの開始、およびトランザクションに対するIDの対応付け
トランザクションのロールバック
トランザクションの準備およびコミット
内容は次のとおりです。
表19-2に、XAライブラリ・サブプログラムを示します。
表19-2 XAライブラリ・サブプログラム
XAサブプログラム | 説明 |
---|---|
|
RMに接続します。 |
|
RMとの接続を切断します。 |
|
トランザクションを開始し、指定のトランザクションID(XID)に対応付けるか、またはプロセスと既存トランザクションを対応付けます。 |
|
指定されたXIDからプロセスを切断します。 |
|
指定されたXIDに対応付けられているトランザクションをロールバックします。 |
|
指定されたXIDに対応付けられているトランザクションを準備します。これは、2フェーズ・コミット・プロトコルの第1のフェーズです。 |
|
指定されたXIDに対応付けられているトランザクションをコミットします。これは、2フェーズ・コミット・プロトコルの第2のフェーズです。 |
|
準備されたヒューリスティックにコミットまたはロールバックされたトランザクションのリストを取得します。 |
|
指定されたXIDに対応付けられているヒューリスティックに完了したトランザクションの情報を消去します。 |
一般に、APでは、xa_open
文字列で実行されるロールを理解する以外に、表19-2に示したサブプログラムについて考慮する必要はありません。
表19-3に示すように、Oracle DatabaseのXAインタフェースには、いくつかの関数が追加されています。
表19-3 Oracle XAインタフェース拡張機能
関数 | 説明 |
---|---|
|
指定されたXA接続のOCIサービス・ハンドルを戻します。 |
|
指定されたXA接続のOCI環境ハンドルを戻します。 |
|
Oracle Databaseエラー・コードをXAエラー・コードに変換します(動的登録にのみ適用可能)。最初のパラメータは、データベースで作業を実行するために使用するサービス・ハンドルです。2番目のパラメータは、Oracle Databaseから戻されるエラー・コードです。この関数は、OCI文から戻されたエラーが |
この項では、Oracle XAライブラリの開発およびインストールについて説明します。
DBAまたはシステム管理者の責任は次のとおりです。
アプリケーション開発者の支援によってオープン文字列を定義します。詳細は、19.3.3項「xa_open文字列の定義」を参照してください。
静的データ・ディクショナリ・ビューDBA_PENDING_TRANSACTIONS
が存在することを確認し、xa_open
文字列で指定したすべてのOracleユーザーに対して、このビューのREAD
またはSELECT
権限を付与します。
自分が作成したペンディング(インダウト)トランザクションをコミットまたはロールバックするOracleユーザーにFORCE
TRANSACTION
権限を付与します。権限の付与には、コマンドCOMMIT
FORCE
local_tran_id
またはROLLBACK
FORCE
local_tran_id
を使用します。
他のユーザーが作成したXAトランザクションをコミットまたはロールバックするOracleユーザーにFORCE
ANY
TRANSACTION
権限を付与します。たとえば、ユーザーBが作成したトランザクションをユーザーAがコミットまたはロールバックする場合、ユーザーAにはFORCE
ANY
TRANSACTION
権限が必要となります。
Oracle Databaseリリース7のクライアント・アプリケーションの場合は、Oracle XAライブラリで使用されるすべてのOracle Databaseアカウントに対して、動的パフォーマンス・ビューV$XATRANS$
のSELECT
権限を付与する必要があります。このビューは、XAライブラリのインストール時に作成されている必要があります。必要な場合は、Oracle DatabaseユーザーSYS
としてSQLスクリプトxaview
.sql
を実行し、このビューを手動で作成できます。
参照: catxpend .sql スクリプトの位置は、使用中のプラットフォーム固有のOracle Databaseのマニュアルを参照してください。 |
オープン文字列情報を使用して、RMをTPM構成にインストールします。TPMベンダーの指示に従ってください。
DBAまたはシステム管理者は、Oracle Databaseに接続するプロセスをTPMシステムが開始することを認識する必要があります。TPMのマニュアルを参照して、このプロセスのためにどのような環境が存在するのか、ユーザーIDは何である必要があるかを判断してください。この環境で$ORACLE_HOME
および$ORACLE_SID
に正しい値が設定されていることを確認してください。
XAトレース・ファイルが書き込まれるディレクトリに対する書込み許可を、そのユーザーIDに対して付与します。
Oracle XAアプリケーションをオンラインにするために、適切なデータベース・インスタンスを起動します。このタスクは、TPMサーバーを開始する前に実行してください。
アプリケーション開発者の責任は次のとおりです。
DBAまたはシステム管理者の支援によってオープン文字列を定義します。19.3.3項「xa_open文字列の定義」を参照してください。
アプリケーションを開発します。
プリコンパイラ用のトランザクション指向のSQL文に関する特別な制限事項を守ってください。
TPMベンダーの指示に従ってアプリケーションをリンクします。
オープン文字列は、トランザクション・モニターがデータベースをオープンするために使用します。オープン文字列内の最大文字数は256文字です。
内容は次のとおりです。
例19-1に示す構文を使用してオープン文字列を定義できます。
次の文字列は、サンプル・パラメータ設定を示しています。
ORACLE_XA+DB=MANAGERS+SqlNet=SID1+ACC=P/username/password +SesTM=10+LogDir=/usr/local/xalog ORACLE_XA+DB=PAYROLL+SqlNet=SID2+ACC=P/username/password +SesTM=10+LogDir=/usr/local/xalog ORACLE_XA+SqlNet=SID3+ACC=P/username/password +SesTM=10+LogDir=/usr/local/xalog
次の各項では、required_fields
およびoptional_fields
プレースホルダに有効なパラメータについて説明します。
注意:
|
例19-1に示したrequired_fields
プレースホルダは、表19-4に示す名前/値ペアのいずれかを指します。
表19-4 xa_open文字列の必須フィールド
構文要素 | 説明 |
---|---|
|
ユーザーおよびパスワード情報が明示的には提供されないことと、オペレーティング・システム認証フォームが使用されることを指定します。詳細は、『Oracle Database管理者ガイド』を参照してください。 |
|
有効なOracle Databaseアカウントのユーザー名とパスワードを指定します。19.3.1項「DBAまたはシステム管理者の責任」で説明したとおり、HRに |
|
システムによりトランザクションが終了されるまでの、あるサービスから次のサービスまで、あるいはサービスからトランザクションのコミットまたはトランザクションまでの最大許容秒数を指定します。たとえば、 たとえば、TPMでクライアントとサーバー間にリモート・サブプログラム・コールが使用されている場合は、 値が |
例19-1に示したoptional_fields
プレースホルダは、表19-5に示す名前/値ペアのいずれかを指します。
表19-5 xa_open文字列のオプション・フィールド
構文要素 | 説明 |
---|---|
|
ローカル・トランザクションが許可されるかどうかを指定します。デフォルト値は |
|
Oracle Databaseプリコンパイラがデータベースの識別に使用する名前を指定します。たとえば、 Oracle Databaseプリコンパイラのデフォルトのデータベースのみを使用する(SQL文で
|
|
Oracle XAライブラリのエラーとトレース情報が格納されるローカル・システム上のパス名を示します。デフォルトは、 |
|
アプリケーションをオブジェクト・モードで初期化するかどうかを指定します。デフォルト値はfalseです。アプリケーションが、 |
|
データベースのオープン時に割り当てられるカーソルの数を指定します。これは、プリコンパイラ・オプション |
|
システムにログインするために使用するOracle Netデータベース・リンクを示します。この文字列は、 サーバー環境変数を制御できない場合は、 |
|
ロックが共有されるかどうかを示します。同じグローバル・トランザクション内の複数のOracle Databaseトランザクション・ブランチには、密結合または疎結合のどちらの方法も使用できます。ブランチが疎結合の場合は、ロックを共有できません。疎結合ブランチの場合は、値を 注意: Oracle RACの実行時に、トランザクション・ブランチが別のOracle RACインスタンスにある場合は、 |
|
|
|
アプリケーションがマルチスレッドかどうかを指定します。デフォルト値は |
|
アプリケーションで高速アプリケーション通知(FAN)を使用するかどうかを指定します。デフォルト値は |
カーソルは、Oracle XAアプリケーションで使用する場合はトランザクションの存続期間のみ有効です。明示的カーソルは、トランザクションが開始した後にオープンし、コミットまたはロールバックの前にクローズする必要があります。
プリコンパイラとのインタフェースでは、次の2つのオプションがあります。
この項の例では、プリコンパイラPro*C/C++を使用しています。
デフォルトのデータベースでプリコンパイラにインタフェースするには、オープン文字列で使用されるDB
=db_name
フィールドが存在しないことを確認してください。このフィールドが存在しない場合は、デフォルトの接続が指定されます。プロセスごとに1つのデフォルト接続のみが使用できます。
次に、デフォルトのPro*C/C++接続を識別するオープン文字列の例を示します。
ORACLE_XA+SqlNet=maildb+ACC=P/username/password +SesTM=10+LogDir=/usr/local/logs
DB
=db_name
が存在せず、空のデータベースID文字列であることを示しています。
SQL文の構文は次のようになります。
EXEC SQL UPDATE Emp_tab SET Sal = Sal*1.5;
指定されたデータベースでプリコンパイラにインタフェースするには、オープン文字列にDB
=db_name
フィールドを含めます。参照するすべてのデータベースは、対応するオープン文字列で指定した同一のdb_name
を参照する必要があります。
アプリケーションには、デフォルト・データベースの他に、名前を指定されたデータベースが1つ以上含まれることがあります。たとえば、あるデータベースで従業員の給与を更新し、別のデータベースでその従業員の部門番号(DEPTNO
)を、第3のデータベースでその従業員の管理者を更新するとします。トランザクション・マネージャに例19-2のようなオープン文字列を構成します。
例19-2 オープン文字列構成のサンプル
ORACLE_XA+DB=MANAGERS+SqlNet=SID1+ACC=P/username/password +SesTM=10+LogDir=/usr/local/xalog ORACLE_XA+DB=PAYROLL+SqlNet=SID2+ACC=P/username/password +SesTM=10+LogDir=/usr/local/xalog ORACLE_XA+SqlNet=SID3+ACC=P/username/password +SesTM=10+LogDir=/usr/local/xalog
例19-2の最後のオープン文字列にDB
=db_name
フィールドはありません。
アプリケーション・サーバー・プログラムでは、次のような宣言を入力します。
EXEC SQL DECLARE PAYROLL DATABASE; EXEC SQL DECLARE MANAGERS DATABASE;
ここでも、デフォルトの接続(DB
フィールドを含まない3番目のオープン文字列に対応)には宣言は必要ありません。
更新を実行するときは、次に示すような文を入力します。
EXEC SQL AT PAYROLL UPDATE Emp_Tab SET Sal=4500 WHERE Empno=7788; EXEC SQL AT MANAGERS UPDATE Emp_Tab SET Mgr=7566 WHERE Empno=7788; EXEC SQL UPDATE Emp_Tab SET Deptno=30 WHERE Empno=7788;
最後の文は、デフォルトのデータベースを参照しているためAT
句はありません。
Oracle Databaseプリコンパイラのリリース1.5.3以上では、次に示す例のように、AT
句に文字ホスト変数を使用できます。
EXEC SQL BEGIN DECLARE SECTION; DB_NAME1 CHARACTER(10); DB_NAME2 CHARACTER(10); EXEC SQL END DECLARE SECTION; ... SET DB_NAME1 = 'PAYROLL' SET DB_NAME2 = 'MANAGERS' ... EXEC SQL AT :DB_NAME1 UPDATE... EXEC SQL AT :DB_NAME2 UPDATE...
注意: XAアプリケーションでは、xa_open を介して作成された以外の接続を作成しないでください。XA以外の接続で実行されるすべての作業は、グローバル・トランザクションの範囲から外れることになり、個別にコミットする必要があります。 |
Oracle XAライブラリを使用するOracle Call Interfaceアプリケーションでは、リソース・マネージャにログインするためにOCISessionBegin
をコールしないでください。ログインは、TPMを介して行うようにしてください。そのようなアプリケーションでは、関数xaoSvcCtx
を実行して、リソース・マネージャへのアクセスに必要なサービス・コンテキスト構造体を取得できます。
環境ハンドルをOCI関数に渡す必要があるアプリケーションでは、そのハンドルを検索するためにxaoEnv
もコールする必要があります。
アプリケーション・サーバーでは同時に複数のOracle Databaseのリソース・マネージャをオープンできるため、適切なサービス・コンテキストを取得するためには適切な引数を使用して関数xaoSvcCtx
をコールする必要があります。
参照: 『Oracle Call Interfaceプログラマーズ・ガイド』 |
XAライブラリを使用する場合、トランザクションは、トランザクションをコミットまたはロールバックするSQL文によっては制御されません。制御は、トランザクションを開始および終了するTMに受け入れられるAPIによって行われます。表19-2に示したXAライブラリ・サブプログラムではなく、表19-6に示したTXインタフェースなど、トランザクション・マネージャにより提供されるAPIをコールします。
TMは、通常、XAインタフェースを介してトランザクションを制御します。このインタフェースには、表19-2に示す関数が含まれています。
表19-6 TXインタフェース関数
TX関数 | 説明 |
---|---|
|
リソース・マネージャにログインします。 |
|
リソース・マネージャからログアウトします。 |
|
トランザクションを開始します。 |
|
トランザクションをコミットします。 |
|
トランザクションをロールバックします。 |
ほとんどのTPMアプリケーションは、アプリケーション・クライアントがサービスを要求し、アプリケーション・サーバーがサービスを提供するというクライアント/サーバー・アーキテクチャを使用しています。「プリコンパイラ・アプリケーションの例」に示す例では、そのようなクライアント/サーバー・モデルを使用しています。サービスとは論理作業単位であり、Oracle DatabaseがRMである場合は、関連する作業単位を実行する一連のSQL文で構成されます。
たとえば、「貸方記入」というサービスが口座番号および貸方記入額を受け取ると、このサービスは、データベース内の特定の表にある情報を更新するSQL文を実行します。また、サービスはその他のサービスを要求することもあります。たとえば、「振替」サービスの場合は、「貸方記入」および「借方記入」にサービスを要求します。
通常、アプリケーション・クライアントは、トランザクション内で作業を実行するためにアプリケーション・サーバーにサービスを要求します。ただし、一部のTPMシステムでは、アプリケーション・クライアント自身がローカルにサービスを提供できます。「プリコンパイラ・アプリケーションの例」に示すとおり、トランザクション制御文は、クライアントまたはサーバーのどちらの側でも記述できます。
複数のプロセスを同一のトランザクションに参加させるために、TPMは参加プロセス間でトランザクション情報が伝達できる通信APIを提供しています。通信APIの例として、RPC、疑似RPC関数、送信/受信関数があります。
主要ベンダーが異なる通信関数をサポートしているため、次の例では、通信APIを汎用化するために通信疑似関数tpm_service
を使用しています。
X/Openの準備段階の仕様には、通信関数を提供する代替方法がいくつか取り入れられています。主要TPMベンダーでは、これらの代替方法を1つ以上はサポートしています。
次の例は、プリコンパイラ・アプリケーションを示しています。アプリケーション・サーバーがTPM固有の方法でRMシステムにログインしているとします。例19-3に、アプリケーション・サーバーによって開始されるトランザクションを示します。
例19-3 アプリケーション・サーバーによって開始されるトランザクション
/***** Client: *****/ tpm_service("ServiceName"); /*Request Service*/ /***** Server: *****/ ServiceName() { <get service specific data> tx_begin(); /* Begin transaction boundary */ EXEC SQL UPDATE ...; /* This application server temporarily becomes */ /* a client and requests another service. */ tpm_service("AnotherService"); tx_commit(); /* Commit the transaction */ <return service status back to the client> }
例19-4に、アプリケーション・クライアントによって開始されるトランザクションを示します。
例19-4 アプリケーション・クライアントによって開始されるトランザクション
/***** Client: *****/
tx_begin(); /* Begin transaction boundary */
tpm_service("Service1");
tpm_service("Service2");
tx_commit(); /* Commit the transaction */
/***** Server: *****/
Service1()
{
<get service specific data>
EXEC SQL UPDATE ...;
<return service status back to the client>
}
Service2()
{
<get service specific data>
EXEC SQL UPDATE ...;
...
<return service status back to client>
}
既存のプリコンパイラまたはOCIアプリケーションを、Oracle XAライブラリを使用するTPMアプリケーションに移行するには、次の手順に従います。
アプリケーション・クライアントがアプリケーション・サーバーにサービスを要求できるように、アプリケーションを「サービス」のフレームワークに再編成します。TPMには、アプリケーションでtx_open
関数およびtx_close
関数を使用するように要求するTPMと、ログインおよびログオフを暗黙的に実行するTPMがあります。
オープン文字列にSqlNet
パラメータを指定しないと、アプリケーションはデフォルトのOracle Netドライバを使用します。このため、ORACLE_HOME
およびORACLE_SID
環境変数を正しく定義して、アプリケーション・サーバーを立ち上げる必要があります。これは、TPMに固有の方法で行われます。これを行う方法の詳細は、TPMベンダーのマニュアルを参照してください。
アプリケーションで正規の接続文および切断文を置き換えます。たとえば、接続文EXEC
SQL
CONNECT
(プリコンパイラの場合)またはOCISessionBegin
、OCIServerAttach
およびOCIEnvCreate
(OCIの場合)をtx_open
で置き換えます。切断文EXEC
SQL
COMMIT
/ROLLBACK
WORK RELEASE
(プリコンパイラの場合)またはOCISessionEnd
/OCIServerDetach
(OCIの場合)をtx_close
で置き換えます。
アプリケーションで、グローバル・トランザクションの正規のコミット文またはロールバック文を置き換え、トランザクションを明示的に開始します。
たとえば、tx_commit/tx_rollback
によってCOMMIT
/ROLLBACK
文のEXEC
SQL
COMMIT
/ROLLBACK
WORK
(プリコンパイラの場合)またはOCITransCommit
/
OCITransRollback
(OCIの場合)を置き換え、tx_begin
をコールすることによってトランザクションを開始します。
注意: 前述の例は、ローカル・トランザクションではなくグローバル・トランザクションにのみ該当します。ローカル・トランザクションは、Oracle APIでコミットまたはロールバックする必要があります。 |
アプリケーションで、トランザクションを終了する前にフェッチ状態をリセットします。一般的には、release_cursor=no
を使用します。release_cursor=yes
は、文が1回しか実行されないことが確実なときにのみ使用します。
表19-7に、プリコンパイラまたはOCIアプリケーションをTPMアプリケーションに移行するときに、正規のOracle Database文を置き換えるTPM関数を示します。
スレッドをサポートするトランザクション・モニターを使用する場合は、Oracle XAライブラリを使用してスレッド・セーフなアプリケーションを作成できます。ただし、注意が必要な問題がいくつかあります。
制御のスレッド(またはスレッド)とは、リソース・マネージャへの一連の接続のことです。スレッド化されていないシステムでは、各プロセスは制御のスレッドとみなされます。これは、各プロセスにはRMへの接続がそれぞれ独自にあり、それぞれが独立したRM表をメンテナンスしているためです。スレッド化されているシステムでは、各スレッドにはRMとの自律型接続があり、プライベートなRM表をメンテナンスします。このプライベートな表はスレッドのそれぞれに対して割り当てる必要があり、またスレッドが終了したときは(異常終了であっても)割当てを解除する必要があります。
注意: Oracle Databaseでは、データベースにアクセスする各スレッドに独自の接続が必要です。 |
内容は次のとおりです。
xa_open
文字列では、Threads=
句が指定されます。TMでスレッドを使用できるようにするには、この句をtrue
に指定する必要があります。デフォルトはfalse
です。ほとんどの場合、スレッドはTMによって作成され、アプリケーションはスレッドがいつ作成されたのか認識しません。このため、サービス・コンテキストは、TMアプリケーション用に作成される各サービス内のスタック上に割り当てることをお薦めします。そのサービス内でOracle Database関連のコールを実行する前に、xaoSvcCtx
関数をコールして初期化済のOCIサービス・コンテキストを取得する必要があります。このコンテキストをサービス内でOCIコールに使用できます。
スレッドを使用するときは、次の制限事項が適用されます。
アプリケーション・スレッドがそれぞれいつ開始されるかが明示的にトランザクション・モニターに通知されないかぎり、トランザクション・モニター上でアプリケーション・サーバー・プロセスの一部として実行されるPro*またはOCIコードをスレッド化することはできません。通常、これは、TMベンダーが提供する特別なCコンパイラを使用して実現されます。
Pro*文EXEC
SQL
ALLOCATE
およびEXEC
SQL
USE
はサポートされません。このため、スレッド化が使用可能であるときは、埋込みSQL文を非XA接続にまたがって使用することはできません。
プロセスの1つのスレッドがXAを介してOracle Databaseに接続した場合、そのプロセスの他のすべてのスレッドもXAを介してOracle Databaseに接続する必要があります。1つのスレッドでEXEC
SQL
CONNECT
を介して接続し、他のスレッドでxa_open
を介して接続することはできません。
PL/SQLアプリケーションは、DBMS_XA
パッケージとともにOracle XAライブラリを使用できます。このパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
例19-5では、1つ目のPL/SQLセッションがトランザクションを開始しますがコミットせず、2つ目のセッションがトランザクションを再開し、3つ目のセッションがコミットします。3つのセッションはすべてHR
スキーマに接続されます。
例19-5 DBMS_XAパッケージの使用
REM Session 1 starts a transaction and does some work. DECLARE rc PLS_INTEGER; oer PLS_INTEGER; xae EXCEPTION; BEGIN rc := DBMS_XA.XA_START(DBMS_XA_XID(123), DBMS_XA.TMNOFLAGS); IF rc!=DBMS_XA.XA_OK THEN oer := DBMS_XA.XA_GETLASTOER(); DBMS_OUTPUT.PUT_LINE('ORA-' || oer || ' occurred, XA_START failed'); RAISE xae; ELSE DBMS_OUTPUT.PUT_LINE('XA_START(new xid=123) OK'); END IF; UPDATE employees SET salary=salary*1.1 WHERE employee_id = 100; rc := DBMS_XA.XA_END(DBMS_XA_XID(123), DBMS_XA.TMSUSPEND); IF rc!=DBMS_XA.XA_OK THEN oer := DBMS_XA.XA_GETLASTOER(); DBMS_OUTPUT.PUT_LINE('ORA-' || oer || ' occurred, XA_END failed'); RAISE xae; ELSE DBMS_OUTPUT.PUT_LINE('XA_END(suspend xid=123) OK'); END IF; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('XA error('||rc||') occurred, rolling back the transaction ...'); rc := DBMS_XA.XA_END(DBMS_XA_XID(123), DBMS_XA.TMSUCCESS); rc := DBMS_XA.XA_ROLLBACK(DBMS_XA_XID(123)); IF rc != DBMS_XA.XA_OK THEN oer := DBMS_XA.XA_GETLASTOER(); DBMS_OUTPUT.PUT_LINE('XA-'||rc||', ORA-' || oer || ' XA_ROLLBACK does not return XA_OK'); raise_application_error(-20001, 'ORA-'||oer|| ' error in rolling back a failed transaction'); END IF; raise_application_error(-20002, 'ORA-'||oer|| ' error in transaction processing, transaction rolled back'); END; / SHOW ERRORS DISCONNECT REM Session 2 resumes the transaction and does some work. DECLARE rc PLS_INTEGER; oer PLS_INTEGER; s NUMBER; xae EXCEPTION; BEGIN rc := DBMS_XA.XA_START(DBMS_XA_XID(123), DBMS_XA.TMRESUME); IF rc!=DBMS_XA.XA_OK THEN oer := DBMS_XA.XA_GETLASTOER(); DBMS_OUTPUT.PUT_LINE('ORA-' || oer || ' occurred, xa_start failed'); RAISE xae; ELSE DBMS_OUTPUT.PUT_LINE('XA_START(resume xid=123) OK'); END IF; SELECT salary INTO s FROM employees WHERE employee_id = 100; DBMS_OUTPUT.PUT_LINE('employee_id = 100, salary = ' || s); rc := DBMS_XA.XA_END(DBMS_XA_XID(123), DBMS_XA.TMSUCCESS); IF rc!=DBMS_XA.XA_OK THEN oer := DBMS_XA.XA_GETLASTOER(); DBMS_OUTPUT.PUT_LINE('ORA-' || oer || ' occurred, XA_END failed'); RAISE xae; ELSE DBMS_OUTPUT.PUT_LINE('XA_END(detach xid=123) OK'); END IF; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('XA error('||rc||') occurred, rolling back the transaction ...'); rc := DBMS_XA.XA_END(DBMS_XA_XID(123), DBMS_XA.TMSUCCESS); rc := DBMS_XA.XA_ROLLBACK(DBMS_XA_XID(123)); IF rc != DBMS_XA.XA_OK THEN oer := DBMS_XA.XA_GETLASTOER(); DBMS_OUTPUT.PUT_LINE('XA-'||rc||', ORA-' || oer || ' XA_ROLLBACK does not return XA_OK'); raise_application_error(-20001, 'ORA-'||oer|| ' error in rolling back a failed transaction'); END IF; raise_application_error(-20002, 'ORA-'||oer|| ' error in transaction processing, transaction rolled back'); END; / SHOW ERRORS DISCONNECT REM Session 3 commits the transaction. DECLARE rc PLS_INTEGER; oer PLS_INTEGER; xae EXCEPTION; BEGIN rc := DBMS_XA.XA_COMMIT(DBMS_XA_XID(123), TRUE); IF rc!=DBMS_XA.XA_OK THEN oer := DBMS_XA.XA_GETLASTOER(); DBMS_OUTPUT.PUT_LINE('ORA-' || oer || ' occurred, XA_COMMIT failed'); RAISE xae; ELSE DBMS_OUTPUT.PUT_LINE('XA_COMMIT(commit xid=123) OK'); END IF; EXCEPTION WHEN xae THEN DBMS_OUTPUT.PUT_LINE ('XA error('||rc||') occurred, rolling back the transaction ...'); rc := DBMS_XA.XA_ROLLBACK(DBMS_XA_XID(123)); IF rc != DBMS_XA.XA_OK THEN oer := DBMS_XA.XA_GETLASTOER(); DBMS_OUTPUT.PUT_LINE('XA-'||rc||', ORA-' || oer || ' XA_ROLLBACK does not return XA_OK'); raise_application_error(-20001, 'ORA-'||oer|| ' error in rolling back a failed transaction'); END IF; raise_application_error(-20002, 'ORA-'||oer|| ' error in transaction processing, transaction rolled back'); END; / SHOW ERRORS DISCONNECT QUIT
内容は次のとおりです。
Oracle XAライブラリでは、すべてのエラーおよびトレース情報がトレース・ファイルに記録されます。この情報は、XAエラー・コードを補足するときに役立ちます。たとえばxa_open
障害が発生したとき、その原因として、オープン文字列が正しくなかったか、Oracle Databaseインスタンスの検索が正常に実行されなかったか、またはログイン認可が正常に実行されなかったかを示します。
トレース・ファイル名はxa_
db_namedate
.trc
です。db_name
はオープン文字列のフィールドDB
=db_name
で指定したデータベース名で、date
は情報がトレース・ファイルに記録された日付です。オープン文字列でDB
=db_name
を指定しない場合、自動的にデフォルトでNULL
になります。
たとえば、xa_NULL06022005
.trc
は、2005年6月2日に作成されたトレース・ファイルを示しています。リソース・マネージャがオープンされたときに、DB
フィールドがオープン文字列に指定されていませんでした。ファイル名xa_Finance12152004
.trc
は、2004年12月15日に作成されたトレース・ファイルを示しています。リソース・マネージャがオープンされたときに、DB
フィールドはオープン文字列で「Finance」と指定されていました。
注意: オープン文字列に同一のDB フィールドおよびLogDir フィールドを持つ複数のOracle XAライブラリRMは、同じ日に発生したすべてのトレース情報を同じトレース・ファイルに記録します。 |
トレース・ファイルに次の内容が含まれているとします。
1032.12345.2: ORA-01017: invalid username/password; logon denied 1032.12345.2: xaolgn: XAER_INVAL; logon denied
表19-8に、各要素の意味を示します。
表19-8 サンプル・トレース・ファイルの内容
文字列 | 説明 |
---|---|
|
情報が記録された時刻 |
|
プロセスID(PID) |
|
リソース・マネージャID |
|
モジュール名 |
|
XA標準での指定に従って戻されたエラー |
ORA-01017 |
戻されたOracle Database情報 |
内容は次のとおりです。
通常、XAトレース・ファイルはエラーが検出された場合にのみオープンされます。xa_open
文字列DbgFl
は、XAライブラリに関する詳細を記録するトレース機能を提供します。デフォルト値は0(ゼロ)です。次の組合せのいずれかに設定できます。
0x1:
XAインタフェース内の各サブプログラムの入口および出口をトレースできます。この値は、TPモニターがどのXAコールを作成し、どのトランザクション識別子を生成しているかを正確に調べるときに役立ちます。
0x2:
他の非公開XAライブラリ・プログラムへの入口および出口をトレースできます。通常、これはOracle Database開発者用の機能です。
0x4
: OCIに対する専用コールのように、XAライブラリが作成する他の様々な関心のあるコールをトレースできます。通常、これはOracle Database開発者用の機能です。
注意: 各フラグはub4 の独立ビットであるため、複数のフラグから出力を取得するには、フラグの値の組合せを設定する必要があります。 |
XAアプリケーションでは、トレース・ファイルの位置が次のアルゴリズムに従って判別されます。
オープン文字列で指定されているLogDir
ディレクトリ。
オープン文字列にLogDir
を指定しないと、Oracle XAアプリケーションは(Oracleホームがアクセス可能な場合は)次のディレクトリにトレース・ファイルを作成しようとします。
%ORACLE_HOME%\rdbms\trace
(Windowsの場合)
$ORACLE_HOME/rdbms/log
(LinuxおよびUNIXの場合)
Oracle XAアプリケーションでは、Oracleホームの位置を判別できない場合、トレース・ファイルは現在の作業ディレクトリに作成されます。
インダウト・トランザクションまたはペンディング・トランザクションとは、準備はできているがデータベースに対してコミットされていないトランザクションです。一般的に、TPMシステムが提供するTMは、インダウト・トランザクションまたはペンディング・トランザクションの障害を解決し、リカバリします。次の状況では、DBAがインダウト・トランザクションをオーバーライドする必要がある場合があります。
他のトランザクションが必要とするデータをロックしている場合
適切な時間の経過後も解決されない場合
前述のような状況でインダウト・トランザクションをオーバーライドする方法の詳細、およびインダウト・トランザクションをコミットまたはロールバックするかどうかを決定する方法の詳細は、TPMのマニュアルを参照してください。
Oracle DatabaseのSYS
アカウントには次のビューがあり、正規のOracle DatabaseアプリケーションおよびOracle XAアプリケーションによって生成されたトランザクションが含まれています。
DBA_PENDING_TRANSACTIONS
V$GLOBAL_TRANSACTION
DBA_2PC_PENDING
DBA_2PC_NEIGHBORS
Oracle XAアプリケーションによって生成されたトランザクションの場合は、次に示す列情報がDBA_2PC_NEIGHBORS
表に適用されます。
DBID
列は常にxa_orcl
DBUSER_OWNER
列は常にdb_name
xa
.oracle
.com
db_nameは、オープン文字列で常にDB
=db_name
と指定されることに注意してください。オープン文字列にこのフィールドを指定しないと、この列の値はOracle XAアプリケーションが生成するトランザクションについてはNULLxa
.oracle
.com
になります。
たとえば、次のSQL文を使用すると、Oracle XAアプリケーションによって生成されたインダウト・トランザクションの詳細情報を取得できます。
SELECT * FROM DBA_2PC_PENDING p, DBA_2PC_NEIGHBORS n WHERE p.LOCAL_TRAN_ID = n.LOCAL_TRAN_ID AND n.DBID = 'xa_orcl';
別の方法として、トランザクション処理モニターが使用するフォーマットID
がわかっている場合は、DBA_PENDING_TRANSACTIONS
またはV$GLOBAL_TRANSACTION
を使用できます。DBA_PENDING_TRANSACTIONS
では準備済トランザクションの両方のリストが提供されますが、V$GLOBAL_TRANSACTIONS
では、すべてのアクティブなグローバル・トランザクションのリストが提供されます。
内容は次のとおりです。
Oracle XAアプリケーションは、次の制限事項に違反しないかぎり、データベース・リンク経由で他のOracle Databaseインスタンスにアクセスできます。
共有サーバー構成を使用する必要があります。
トランザクション処理モニター(TPM)は、共有サーバーを使用してOracle Database Aへの接続をオープンします。データベース・リンクに必要なオペレーティング・システム・ネットワーク接続は、専用サーバー・プロセスではなくディスパッチャによってオープンされます。このため、様々なサービスやスレッドでトランザクションを操作できます。
この制限事項が満たされていない場合、XAトランザクション内でデータベース・リンクを使用すると、専用サーバー・プロセスと他方のOracle Database Bの間にオペレーティング・システム・ネットワーク接続が作成されます。このネットワーク接続は専用サーバー・プロセス間で移動できないため、データベースAのこの専用サーバー・プロセスから連結解除することはできません。データベース・リンクを介してデータベースBにアクセスするときに、ORA-24777エラーが戻されます。
アクセスする他のデータベースは、別のOracle Databaseである必要があります。
この制限事項が満たされている場合、Oracle Databaseはデータベース・リンクを許可し、トランザクション・プロトコルを他のOracle Databaseインスタンスに伝播(準備、ロールバックおよびコミット)します。
共有サーバー構成を使用できない場合は、リモート・データベースにEXEC
SQL
AT
構文を使用してPro*C/C++アプリケーション経由でアクセスします。
init.ora
パラメータOPEN_LINKS_PER_INSTANCE
は、移行可能なオープン・データベース・リンク接続の数を指定します。これらのdblink
接続は、トランザクションのコミット後に接続をキャッシュできるように、XAトランザクションによって使用されます。接続を作成したユーザーがトランザクションも作成した場合、別のトランザクションがデータ・リンク接続を使用できます。このパラメータは、1つのセッションにおけるリモート・データベースへの同時オープン接続の最大数(データベース・リンクを含む)を指定するinit
.ora
パラメータOPEN_LINKS
とは異なります。OPEN_LINKS
パラメータは、XAアプリケーションには適用できません。
同じグローバル・トランザクション内の複数のOracle Databaseトランザクション・ブランチには、密結合または疎結合のどちらの方法も使用できます。トランザクション・ブランチが密結合の場合は、ロックを共有できます。そのため、あるトランザクション・ブランチでのCOMMIT
前更新は、同じグローバル・トランザクションに属する他のブランチで参照可能です。疎結合トランザクション・ブランチの場合、ブランチはロックを共有せず、他のブランチでの更新を認識しません。
密結合ブランチの場合、Oracle Databaseは文を実行する前にDXロックを取得します。システムが文の実行前にロックを取得しないため、疎結合トランザクション・ブランチの同時実行性が増します。デメリットは、すべてのトランザクション・ブランチが2フェーズ・コミットを実行する必要があることです。XAの1フェーズ最適化は使用できません。
表19-9に、密結合ブランチと疎結合ブランチのトレードオフを示します。
Oracle Database 11gリリース1(11.1)では、XAトランザクションは複数のOracle RACインスタンスにまたがって、XAを使用するすべてのアプリケーションでOracle RAC環境を活用し、アプリケーションの可用性とスケーラビリティを拡張できるようになりました。
注意: 分散トランザクションと組み合せた外部プロシージャ・コールアウトはサポートされません。 |
内容は次のとおりです。
初期化パラメータGLOBAL_TXN_PROCESSES
は、各Oracle RACインスタンスのGTXnバックグラウンド・プロセス数を指定します。デフォルト値は1です。
分散トランザクションが複数のOracle RACインスタンスにまたがる場合、このパラメータはクラスタ全体でデフォルト値のままとします。これにより、Oracle RACインスタンス全体にわたって実行される作業単位は、リソースを共有し、単一のトランザクションとして機能します(つまり、作業単位は密結合となります)。また、クラスタ内の任意のノードへの2フェーズ・コミット要求の送信も可能となります。
参照: GLOBAL_TXN_PROCESSES の詳細は、『Oracle Databaseリファレンス』を参照してください。 |
注意: このトピックは、次のいずれかが当てはまる場合に適用されます。
|
Oracle Databaseでは、様々なインスタンスがOracle RACの異なるトランザクション・ブランチで操作できます。たとえば、ノード1がブランチAで操作し、ノード2がブランチBで操作できます。Oracle Database 11gリリース1(11.1)より前は、トランザクション・ブランチが異なるインスタンスにある場合は疎結合であり、ロックを共有しませんでした。この場合、Oracle Databaseでは、様々なアプリケーション・スレッドの異なる作業単位が、リソースを共有しない個別エンティティとして処理されました。
また、複数のインスタンスが1つのトランザクション・ブランチで操作する場合もあります。たとえば、次のように1つのトランザクションがノード1およびノード2にあるとします。
ノード1
xa_start
SQL操作
xa_end
(SUSPEND)
ノード2
xa_start
(RESUME)
xa_prepare
xa_commit
xa_end
直前の順序では、ノード2は物理的に異なるノード(ノード1)にあるブランチを再開しないため、Oracle Databaseではエラーが戻されます。
Oracle Database 11gリリース1 (11.1)より前のリリースでは、Oracle RACで密結合を実現する方法として分散トランザクション処理(DTP)サービス、つまりカーディナリティ(1)によって、ロード・バランシングが有効かどうかに関係なくすべての密結合ブランチが確実に同じインスタンスに配置されるサービスを使用していました。中間層コンポーネントは、常に1つのOracle RACインスタンスにマップする共通の論理データベース・サービス名を使用して、Oracle Databaseをアドレス指定しました。データベース・インスタンスの物理特性は、データベース・サービスの中間名リゾルバによって隠されました。DTPサービスを使用すると、密結合グローバル・トランザクションの参加者はすべて1つのインスタンス上でブランチを作成できました。
Oracle Database 11gリリース1 (11.1)では、密結合ブランチでのXAトランザクションのサポートにDTPサービスは不要になりました。デフォルトでは、異なるOracle RACインスタンスにある密結合ブランチは密結合のままとなります。つまり、Oracle RACインスタンス全体でロックとリソースを共有します。
たとえば、DTPサービスを使用すると、次の一連のアクションが同じインスタンス上で発生します。
xa_start
SQL操作
xa_end
(SUSPEND)
xa_start
(RESUME)
SQL操作
xa_prepare
xa_commit
またはxa_rollback
さらに、それぞれが同じDTPサービスでOracle RMをアドレス指定する場合は、複数の密結合ブランチが同じインスタンスにあります。
クラスタのインスタンスをすべて活用するには、分散トランザクションを管理する各ノードに1つ以上、複数のDTPサービスを作成します。グローバル分散トランザクションのブランチは、すべて同じインスタンスに存在します。そのため、Oracle RACクラスタのすべてのインスタンスおよびノードを利用して多数の分散XAトランザクションのロード・バランシングを実行し、アプリケーションのスループットを最大化できます。
参照: Real Application Clusters構成で分散トランザクションを管理する方法は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照してください。 |
Oracle Database 10gリリース2(10.2)より前は、Oracle RACでの障害検出とフェイルオーバーおよびフェイルバックのトリガーはTMで実行されていました。インダウト・トランザクションに関する情報をDBA_2PC_PENDING
に確実に伝播させるために、TMではインダウト・トランザクションの解決に進む前にxa_recover
を起動する必要がありました。インスタンスに障害が発生した場合、XAクライアント・ライブラリはSYS.DBMS_XA.DIST_TXN_SYNC
プロシージャを実行して障害を起こしたインスタンスのUNDOセグメントがリカバリされたことを確認するまで、他のインスタンスにフェイルオーバーできませんでした。Oracle Database 10gリリース2(10.2)では、処理中のトランザクションに関する十分な情報がTMにあれば、このようにxa_recover
を起動するという要件はありません。
注意: Oracle Database 9gリリース2(9.2)以降のリリースでは、xa_recover はリモート・サイトで分散データ操作言語(DML)が完了するまで待機する必要があります。 |
Oracle RACでDTPサービスを使用すると、次のようなメリットがあります。
インスタンス障害の検出が自動化されます。
インスタンスのフェイルオーバーとフェイルバックが自動化されます。インスタンスに障害が発生すると、このインスタンスで管理されているDTPサービスが他のインスタンスにフェイルオーバーします。このフェイルオーバーにより、クライアントは強制的に再接続されますが、サービスの論理名は変わりません。フェイルオーバーは自動的で、管理者が介入する必要はありません。管理者は、サービス再配置文を使用してフェイルバックを実行できますが、フェイルバック関連のリカバリはすべてデータベース・サーバー内で自動的に処理されます。
クライアントではなくOracle Databaseがインスタンスのリカバリを実行できます。データベースでは、中間層TMの関与を必要とせずに、他のインスタンスによって準備されたトランザクションの状態を判別できます。
参照:
|
Oracle Database 11gリリース1(11.1)より前のリリースでは、Oracle RACデータベースでは指定されたXIDがクラスタ内のXAトランザクションで一意であるかどうかは判断できません。
たとえば、Oracle RACインスタンス1にXID Fmt(
x
)
.Tx(1)
.Br(1)
、Oracle RACインスタンス2に別のXID Fmt(
x
)
.Tx(1)
.Br(1)
があるとします。XIDがOracle RACインスタンス間で一意ではありませんが、どちらもブランチを開始してSQLを実行できます。
Oracle Database 11gリリース1 (11.1)では、Oracle RACデータベースはOracle RACインスタンス間の重複するXIDを検出し、重複したXIDを持つブランチが開始しないようにしています。
参照: Oracle RACでのサービスおよび分散トランザクション処理の詳細は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照してください。 |
同じグローバル・トランザクション内の複数のOracle Databaseトランザクション・ブランチには、密結合または疎結合のどちらの方法も使用できます(詳細は、19.5.2項「Oracle XAアプリケーションでのトランザクション・ブランチの管理」を参照してください)。通常、結合のタイプはxa_open
文字列のLoose_Coupling
フィールドで定義します(詳細は、表19-5を参照してください)。ただし、Oracle RACの実行時に、トランザクション・ブランチが別のOracle RACインスタンスにある場合は、Loose_Coupling=false
であってもこれらは疎結合です。
参照: Oracle RACでのサービスおよび分散トランザクション処理の詳細は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照してください。 |
この項では、次のSQL操作に関する制限事項について説明します。
グローバル・トランザクションの進行状況の調整および監視はトランザクション・マネージャが行うため、グローバル・トランザクションのロールバックまたはコミットを独立して行うOracle Database固有の文をアプリケーションに入れないでください。ただし、ローカル・トランザクションではロールバックおよびコミットを使用できます。
グローバル・トランザクションの途中で、プリコンパイラ・アプリケーションにEXEC
SQL
ROLLBACK
WORK
を使用しないでください。同様に、OCIアプリケーションでは、OCITransRollback
またはバージョン7で同等のorol
を実行しないでください。グローバル・トランザクションをロールバックするには、tx_rollback
をコールします。
同様に、グローバル・トランザクションの途中で、プリコンパイラ・アプリケーションにEXEC
SQL
COMMIT
WORK
文を使用しないでください。OCIアプリケーションでは、OCITransCommit
またはバージョン7で同等のocom
を実行しないでください。たとえば、tx_commit
またはtx_rollback
を使用して、グローバル・トランザクションを終了してください。
Oracle Databaseでは、セッション状態が複数のTPMサービス間で有効であることを保証しません。たとえば、あるTPMサービスがセッション変数(グローバル・パッケージ変数など)を更新した場合、同じグローバル・トランザクションの一部として実行している別のTPMサービスにはこの変更が認識されないことがあります。セーブポイントは1つのTPMサービス内で使用してください。アプリケーションが、別のTPMサービスで作成されたセーブポイントを参照しないようにしてください。同様に、アプリケーションが、別のTPMサービスで実行されたカーソルからフェッチしないようにしてください。
接続および切断にEXEC
SQL
文を使用しないでください。つまり、EXEC
SQL
CONNECT
、EXEC
SQL
COMMIT
WORK
RELEASE
またはEXEC
SQL
ROLLBACK
WORK
RELEASE
を使用しないでください。
EXEC
SQL
SET
TRANSACTION
はトランザクションの最初の操作である必要があります。
トランザクションに複数のブランチがある場合、1つのブランチのみにトランザクション名を設定することができます。それ以外の場合は、エラーORA-1453が発生します。
Oracle XAとゲートウェイの両方を同じセッションで使用できません。
Oracle Databaseでは、関連付けの移行はサポートされません(関連付けの移行とは、トランザクション・マネージャが中断中のブランチ関連付けを別のブランチで再開する手段です)。
XAのオプションの機能である非同期XAコールはサポートされません。
TRANSACTIONS
初期化パラメータを、グローバル・トランザクションの同時実行予測数に設定します。初期化パラメータOPEN_LINKS_PER_INSTANCE
は、移行可能なオープン・データベース・リンク接続の数を指定します。これらのデータベース・リンク接続は、トランザクションのコミット後に接続をキャッシュできるように、XAトランザクションによって使用されます。
スレッドごとのxa_open
コールの最大数は32です。
TPモニター・ベースのXAアプリケーションを構築する場合、リンク・ラインで、TPモニター・ライブラリ(ax_reg
およびax_unreg
記号を定義する)をOracle Databaseクライアント共有ライブラリの前に指定する必要があります。プラットフォームで共有ライブラリがサポートされていない場合、またはリンカーがリンク・ライン内のライブラリの順序を区別しない場合は、Oracle Databaseの非共有クライアント・ライブラリを使用します。これらのリンク制限は、XAの動的登録(Oracle XAスイッチxaoswd
)を使用する場合のみ適用できます。