4 Microsoft Transaction ServerおよびOracle Databaseを使用したプログラミング
これらのトピックでは、Microsoft Transaction ServerおよびOracle Databaseを使用したプログラミング方法について説明します。
OraMTSでは、Oracle Provider for OLE DBおよびOracle Data Provider for .NETとの統合も可能になります。
関連項目:
-
MTSでのOracle Provider for OLE DBの使用方法の詳細は、『Oracle Provider for OLE DB開発者ガイドfor Microsoft Windows』を参照してください。
-
MTSでのOracle Data Provider for .NETの使用方法の詳細は、『Oracle Data Provider for .NET開発者ガイド』(Microsoft Windows用)を参照してください。
4.1 トランザクション内でのCOMコンポーネント統合
トランザクション処理の中心となるのは、Microsoft分散トランザクション・コーディネータ(MS DTC)と呼ばれるMicrosoft Transaction Serverのコンポーネントです。クライアント・コンピュータがトランザクション・コンポーネントでビジネス・メソッドを起動すると、Microsoft Transaction ServerはMS DTCによって調整されるトランザクションを開始します。Oracle接続をプールしているレイヤーにより、データベースはMS DTCによって調整されるトランザクション内でリソース・マネージャ(RM)として機能します。図4-1はこのトランザクション・モデルを表しています。
クライアント・コンピュータ
クライアント・コンピュータは、WebブラウザやComponent Object Model (COM)/Distributed Component Object Model (DCOM)を通じてMTSアプリケーション・サーバー上のアプリケーション・コンポーネントをアクティブにします。
MTSアプリケーション・サーバー
MTSアプリケーション・サーバーは、クライアント・コンピュータがWebブラウザを通じて間接的に、またはComponent Object Model (COM)/Distributed Component Object Model (DCOM)を通じて直接的にアクティブ化できるトランザクション・アプリケーション・コンポーネントをホストするためにWindowsオペレーティング・サービスによって提供されるサービスで構成されます。このアプリケーション・サーバーは、クライアントのリクエストに応じてCOMコンポーネントを起動します。起動は、必要に応じてトランザクションのスコープ内で実行されます。
トランザクション・アプリケーション・ロジックCOMコンポーネント
主に次の3つの役割を果たします。
-
ビジネス・ロジックの埋込み。コンポーネントがトランザクションの場合、Microsoft Transaction Serverにより、そのコンポーネントでメソッドが起動されるたびにトランザクションが開始されます。
-
Oracleリソース・ディスペンサと、Oracle Call Interface (OCI)、Oracle Open Database Connectivity (ODBC) DriverまたはOracle Provider for OLE DBを通じて、Oracle Databaseへのプール済の接続を取得。
-
変更をすべてのRMにコミットするか終了するかの決定をMicrosoft Transaction Serverに通知することによって、処理の結果を決定。
Oracle ODBCドライバ、Oracle Provider for OLE DB、およびOCI
主に次の2つの役割を果たします。
-
Oracle Databaseへのサービス・コンテキストを、OCI接続プール・コンポーネントを通じて取得。
-
必要に応じて、プールしている接続リソースを(Oracle Provider for OLE DBまたはOracle ODBCドライバを通じて)提供。Oracle ODBCドライバは、プール済のODBC接続を提供します。Oracle Provider for OLE DBは、プール済のデータソース・オブジェクトを提供します。
OCI接続プール
主に次の3つの役割を果たします。
-
RM(Oracle Database)としてコンポーネントのMicrosoft Transaction Serverトランザクションに登録。
-
コンポーネントが属するMicrosoft Transaction Serverトランザクションに対応するOracleグローバル・トランザクションを開始。
-
クライアント側の接続プーリングを実行するリソース・ディスペンサとして機能。
Oracle Net
異機種分散コンピュータ環境で接続を提供します。
Oracle MTS Recovery Service
ホスト・コンピュータで開始され、Microsoft Transaction Serverと連携するインダウトOracleトランザクションをリカバリします。
データベース・リカバリ・ジョブ
インダウトDTCトランザクションを検出します。このジョブは、インダウト・トランザクションのXIDから、リカバリ・サービスのエンドポイントのアドレスを抽出し、リカバリ・サービスからMicrosoft DTCトランザクションの結果を要求します。最終的に、トランザクションの結果を受け取ると、このジョブはインダウト・トランザクションをコミットまたは終了します。
Microsoft DTC
Microsoft分散トランザクション・コーディネータは、Microsoft Transaction Serverの一部であり、次に示す2つの主要な役割があります。
-
2フェーズ・コミット・プロトコルを使用して、トランザクションをコミットまたは終了。
-
リカバリが必要なトランザクションを監視。1つのトランザクションに複数のMS DTCを関与させることができます。コンピュータAにあるMicrosoft Transaction Serverのトランザクション・コンポーネントが、コンピュータBにあるMicrosoft Transaction Serverの別のトランザクション・コンポーネントを起動すると、コンピュータAのMS DTCとコンピュータBのMS DTC間で接続がオープンされます。ルートMS DTCがトランザクションをコミットまたは終了するときには、関与するすべてのMS DTCを通じて要求を送信します。このトランザクション要求はOCI接続プール/Microsoft Transaction Server統合に渡され、そこからデータベースに送られます。
Oracleデータベース
Microsoft Transaction ServerのRMとして機能します。このデータベース上で、クライアントのトランザクション要求が実行されます。
4.2 Microsoft Transaction Serverアプリケーションの開発
OCI接続プールは、ほとんどすべてのアプリケーション・プログラミング・インタフェースで、トランザクションの調整に利用されます。このトピックでは、トランザクションの登録方法、およびOCI接続プールでトランザクションを調整する方法について説明します。
4.2.1 Microsoft Transaction Serverコンポーネントの登録
Microsoft Transaction Server環境で実行されるアプリケーション・コンポーネントは、Dynamic Link Library(DLL)として作成されます。アプリケーション・コンポーネントは、Graphical User Interface(GUI)ツールのMicrosoft Transaction Serverエクスプローラを使用してMicrosoft Transaction Serverに登録されます。
4.2.1.1 登録コンポーネントのタイプ
アプリケーション・コンポーネントを登録するときには、次のいずれかのタイプを指定します。
-
トランザクションが必要: コンポーネントはトランザクションで実行する必要があります。現在トランザクションが存在しない場合は、Microsoft Transaction Serverにより、コンポーネントでメソッドが起動されるたびに新しいトランザクションが自動的に作成されます。
-
トランザクションをサポート: コンポーネントは、クライアントのトランザクション内で実行できます。新しいコンポーネントが作成されると、そのコンテキストは起動元クライアントのコンテキストからトランザクションを継承します。クライアントにトランザクションがない場合は、新しいコンテキストもトランザクションなしで作成されます。
-
新しいトランザクションが必要: コンポーネントは、専用のトランザクション内で実行する必要があります。Microsoft Transaction Serverにより、コンポーネントでメソッドが起動されるたびに新しいトランザクションが自動的に作成されます。
-
トランザクションをサポートしない: コンポーネントはトランザクション内で実行されません。起動元のクライアントにトランザクションがあるかどうかにかかわらず、コンポーネントでの各メソッドの起動はそれを含むトランザクションなしで実行されます。
4.2.1.2 コンポーネントの登録
アプリケーション・コンポーネントの登録方法により、そのコンポーネントがMicrosoft Transaction Serverによって調整されるトランザクション内で実行されるかどうかが決まります。
-
アプリケーション・コンポーネントがMicrosoft Transaction Serverによって調整されるトランザクションで実行される場合、常にOCI接続プールが使用され、Microsoft Transaction ServerおよびそのMS DTCコンポーネントにより、トランザクションの作成、開始、管理およびコミットが調整されます。Microsoft Transaction Serverにより、コンポーネントが行ったすべての変更は、トランザクションが成功した場合はコミットされ、失敗した場合は終了されます。
-
アプリケーション・コンポーネントがMicrosoft Transaction Serverによって調整されるトランザクションで実行されない場合、このコンポーネントはMicrosoft Transaction Server環境で実行されますが、コンポーネントがアクセスするデータベースは、MS DTCによって調整されるトランザクションに登録される場合とされない場合があります。MS DTCによって調整されないトランザクションの場合は、クライアント・アプリケーションがトランザクションの作成、開始、管理およびコミットを行う必要があります。データベースにアクセスするインタフェース(Oracle Provider for OLE DB、Oracle ODBCドライバ、その他)によっては、OCI接続プールが使用される場合があります。
4.2.2 Microsoft Transaction Serverにより調整されるコンポーネントのトランザクション
このトピックでは、Microsoft Transaction Serverによって調整されるトランザクション環境で、OCI接続プール、Microsoft Transaction ServerおよびMS DTCがアプリケーション・コンポーネントでどのように機能するかを説明します。
-
クライアントAPI (Oracle ODBCドライバ、OCI、ODP.NETまたはOracle Provider for OLE DBのいずれか)がOCI関数
OraMTSSvcGet()
をコールして、OCI接続プール・コンポーネントからサービス・コンテキストを取得します。 -
OCI接続プール・コンポーネントがトランザクションを登録します。このトランザクションは、Microsoft Transaction ServerのMS DTCコンポーネントによって調整されます。
OCIサービスおよび環境ハンドルはクライアント・アプリケーションに返されます。
-
クライアント・アプリケーションが次の処理を実行します。
-
データベース処理を実行します。
-
OCI関数
OraMTSSvcRel()
をコールして、トランザクションの開始時に取得したOCI接続プールを解放します。 -
コンポーネントに関連付けられたMicrosoft Transaction Serverのコンテキスト・オブジェクトに対して、
SetComplete
(データベース処理をコミットする場合)またはSetAbort
(データベース処理を終了する場合)をコールします。
-
-
MS DTCが2フェーズ・コミット・プロトコルを実行し、トランザクションを準備およびコミットするか、または終了します。これにより、OCI接続プール・コンポーネントに通知が送られ、トランザクションが終了します。
-
OCI接続プールは通知を受信し、フェーズ1(フェーズの準備)およびフェーズ2(フェーズのコミットまたは終了)の完了に必要な手順を実行します。
4.2.3 Microsoft DTCにより調整されるコンポーネントのトランザクション
このトピックでは、Microsoft Transaction Serverによって調整されるトランザクション内で実行されていないがMS DTCを使用しているアプリケーション・コンポーネントで、OCI接続プール、Microsoft Transaction ServerおよびMS DTCがどのように機能するかを説明します。
-
クライアント・アプリケーションは、MS DTCトランザクションを開始し、Oracle Databaseに接続します。接続プロトコルは、次のいずれかのシナリオのようになります。
-
プールされていないOCI接続は、
OCIServerAttach()
やOCISessionBegin()
など、OCIログオン・コールを通じて取得されます。このような接続の場合、アプリケーションはOraMTSEnlCtxGet()
をコールして、OCIサービス・コンテキストをMicrosoft Transaction Serverの登録コンテキストに関連付けます。 -
接続プールは、
OraMTSSvcGet(..,..,ORAMTS_CFLG_NOIMPLICIT)
をコールすることで取得されます。
-
-
クライアントは、次のいずれかのシナリオでコンテキストを処理します。
-
プールされていない接続の場合、クライアント・アプリケーションは登録コンテキストを
OraMTSJoinTxn()
に渡します。 -
プール済の接続の場合、クライアント・アプリケーションはOCIサービス・コンテキストを
OraMTSSvcEnlist()
に渡します。
-
-
OCI接続プール・コンポーネントが、接続(プール済またはプールされていない)を、Microsoft Transaction ServerのMS DTCコンポーネントによって調整されるトランザクションに登録します。
-
その後、クライアント・アプリケーションは次の処理を実行します。
-
データベース処理を実行します。
-
NULL
トランザクション参照でOraMTSSvcEnlist()
をコールし、MS DTCによって調整されるトランザクションから登録解除します。プールされていない接続の場合、
NULL
トランザクション参照でOraMTSTxnJoin()
がコールされ、登録解除が実行されます。 -
OraMTSSvcRel()
をコールし、プール済の接続を解放してプールに戻します。プールされていない接続の場合、クライアントは
OraMTSEnlCtxRel()
をコールして登録コンテキストを解放した後、データベースからログオフします。 -
MS DTCトランザクション・オブジェクトに対して、
pTransaction->Commit()
やpTransaction->Abort()
のような、コミット・メソッドまたは終了メソッドをコールします。
-
-
MS DTCが2フェーズ・コミット・プロトコルを実行し、トランザクションをコミットします。
-
OCI接続プールは通知を受信し、フェーズ1(フェーズの準備)およびフェーズ2(フェーズのコミットまたは終了)の完了に必要な手順を実行します。
4.3 Microsoft Transaction ServerとのOCI統合
例4-1は、OCIとMTSサーバーを統合する方法を表しています。コードを変更しなければならないのは、OCIサービス・コンテキスト・ハンドルの取得および解放の部分のみです。OraMTSSvcGet()
をコールして、データベースへのプール済のOCI接続を取得するときに、OCIサービス・コンテキスト・ハンドルおよび環境ハンドルの両方が取得されます。oramts.h
ヘッダーをインクルードして、oramts.lib
ライブラリとリンクします。それが終了したら、OCI関数OraMTSSvcRel()
をコールして、サービス・コンテキスト・ハンドルおよび環境ハンドルを解放します。アプリケーション・コンポーネントをMicrosoft Transaction Serverトランザクション内で実行するように登録した場合、OraMTSSvcGet()
を使用すると、接続プールおよび暗黙的なトランザクション・サポートが得られるようになります。
各プロセスで、他のOCIコールを実行する前に、OCIInitialize
を1回以上コールするようにしてください。これにより、OCIプロセス環境が初期化されます。また、OCI_THREADED
フラグをそれに渡す必要があります。Microsoft Internet Information Server(IIS)を使用している場合、コンポーネントがインプロセス・ライブラリとしてコールされていれば、OCIInitialize
はすでにコールされています。レジストリ・キーORAMTS_OCI_OBJ_MODE
は追加済です。この値を1に設定し、OCIをオブジェクト・モードで初期化します(そうしないと、OCIはスレッド・モードで初期化されます)。
例4-1 MTSとOCIの統合
#include <oci.h>
#include <oramts.h>
#include <xolehlp.h>
// other MTS relevant includes ...
// prototype for the error handler.
BOOL Chekerr(sword swOCIStat, OCIError *OCIErrh);
// MTS component method
HRESULT OCITestMethod()
{
IObjectContext *pObjectContext = NULL;
OCIEnv *myenvh = NULL;
OCISvcCtx *mysvch = NULL;
OCIError *myerrh = NULL;
OCIStnt *mystmh = NULL;
DWORD dwStat;
HRESULT hRes = S_OK;
sword swOCIStat;
BOOL bCommit = FALSE;
char *lpzStmt = "UPDATE EMP SET SAL = SAL + 1000";
// Initialize the OCI environment first -- request OCI_THREADED
OCIInitialize(OCI_THREADED, (dvoid*)NULL,NULL,NULL,NULL);
// attempt to get a connection to the database through the resource dispenser
OraMTSSvcGet(
"hr","hr_password","finprod_db",&mysvch, &myenvh, ORAMTS_CFLG_ALLDEFAULT);
// validate return status
if(dwStat != ORAMTS_ERR_NOERROR)
{
printf("error: failed to obtain a connection to the database - %ld",
dwStat);
goto cleanup;
}
// successful logon and enlistment in the MTS transaction. allocate statement
// handles and other handles using the OCI environment handle myenvh ....
swOCIStat = OCIHandleAlloc(myenvh, (void *)&myerrh,OCI_HTYPE_ERROR, 0 , NULL);
if (Checkerr(swOCIStat, myerrh)) goto cleanup;
swOCIStat = OCIHandleAlloc(myenvh, (dvoid *)&mystmh,OCI_HTYPE_STMT, 0,NULL);
if (Checkerr(swOCIStat, myerrh)) goto cleanup;
// prepare a DML statement
OCIStmtPrepare(mystmh, myerrh, lpzStmt, lstrlen(lpzStmt), OCI_NTV_SYNTAX,
OCI_DEFAULT)
Checkerr(swOCIStat, myerrh);
// execute the statement -- ensure that AUTOCOMMIT is not requested.
OCIStmtExecute(mysvch, mystmh, myerrh, 1, 0, NULL, NULL, OCI_DEFAULT);
if (Checkerr(swOCIStat, myerrh)) goto cleanup;
// all's well so far choose to go for a commit
bCommit = TRUE;
cleanup:
if (mystmh) OCIHandleFree((void*)mystmh, OCI_HTYPE_STMT);
if (myerrh OCIHandleFree((void*)myerrh, OCI_HTYPE_ERROR);
if (mysvch) OraMTSSvcRel(mysvch);
if (bCommit)
pObjectContext->SetComplete();
else
pObjectContext->Abort();
return(bCommit ? S_OK : E_FAIL);
}
4.3.1 COMコンポーネントの統合
COMコンポーネントの統合には、いくつかのシナリオがあります。Microsoft Transaction Server環境でホストされていないCOMアプリケーション(スタンドアロン・アプリケーション)は、Microsoft Transaction ServerエクスプローラのMicrosoft管理コンソールを通じて宣言トランザクションを使用することはできませんが、次に示すシナリオのうち、最後の3つを使用できます。
4.3.1.1 MTSによって調整されるトランザクション内で実行されるCOMコンポーネント
MTSによって調整されるトランザクションで実行されるCOMコンポーネントは、OCI接続プールを使用して、トランザクションにデータベースを暗黙的に登録します。次の擬似コード・リストは、OCI関数の使用方法を示しています。
OCIInitialize(OCI_THREADED, ...) OraMTSSvcGet(..., &OCISvc, ..., ORAMTS_CFLAG_ALLDEFAULT) ... OraMTSSvcRel(OCISvc)
4.3.1.2 OCI接続プールで実行される、トランザクション以外のCOMコンポーネント
トランザクションではないと指定され、かつMTSによって調整されるトランザクションで実行されるCOMコンポーネントは、OCI接続プールを使用しますが、トランザクションにデータベースを登録しません。次の擬似コード・リストは、OCI関数の使用方法を示しています。
OCIInitialize(OCI_THREADED, ...) OraMTSSvcGet(..., &OCISvc, ..., ORAMTS_CFLAG_NOIMPLICIT) ... OraMTSSvcRel(OCISvc)
4.3.1.3 MS DTCおよびOCI接続プールを使用するCOMコンポーネント
MTSによって調整されるトランザクションで実行されていないCOMコンポーネントは、OCI接続プールとともにMS DTCを使用して、トランザクションにデータベースを明示的に登録します。次の擬似コード・リストは、OCI関数の使用方法を示しています。
OCIInitialize(OCI_THREADED, ...) DTCGetTransactionManager(...) BeginTransaction(..., &transaction) OraMTSSvcGet(..., &OCISvc, ..., ORAMTS_CFLAG_NOIMPLICIT) OraMTSSvcEnlist(OCISvc, ..., transaction, ...) ... OraMTSvcEnlist(OCISvc, ..., NULL, ...) OraMTSSvcRel(OCISvc)
4.3.1.4 MS DTCおよびプールされていないOCI接続を使用するCOMコンポーネント
MTSによって調整されるトランザクションで実行されていないCOMコンポーネントは、プールされていないOCI接続とともにMS DTCを使用して、トランザクションにデータベースを明示的に登録します。次の擬似コード・リストは、OCI関数の使用方法を示しています。
OCIInitialize(OCI_THREADED, ...) OCI to get connected OraMTSEnlCtxGET DTCGetTransactionManager(...) BeginTransaction(..., &transaction) OraMTSJoinTxn (OCISvc, ..., transaction, ...) ... OraMTSJoinTxn ... OraMTSEnlCtxRel() OCI to logoff
4.3.2 OCI関数の使用方法
このトピックでは、前述のOCI関数について詳しく説明します。表4-1ではこれらの関数をまとめています。
表4-1 MTSおよびOracle Databaseを統合するためのOCI関数のサマリー
OCI関数 | 概要 |
---|---|
OCI接続プールから、プール済接続を取得します。 |
|
プール済のOCI接続(OCIサービス・コンテキスト)を解放して接続プールに戻します。 |
|
MS DTCによって調整されるトランザクションにOCI接続を登録または登録解除します。 |
|
OCI接続またはサービス・コンテキストをMS DTCトランザクションに登録します。 |
|
プールされていないOCI接続の登録コンテキストを作成します。 |
|
以前に設定したプールされていないOCI接続の登録コンテキストを破棄します。 |
|
プールされていないOCI接続をMS DTCトランザクションに登録します。 |
|
Microsoft Transaction Serverで開始されたトランザクションの内部で実行されているかどうかをテストします。 |
|
OCIエラー・コードとメッセージ・テキストを取り出します。 |
4.3.3 OraMTSSvcGet()
OCI接続プールからプール済の接続(OCIサービス・コンテキスト)を取得します。プール済の接続には、OCIサービス・コンテキスト・ハンドルおよびOCI環境ハンドルが含まれます。
構文
DWORD OraMTSSvcGet(
text* lpUname, text* lpPsswd, text* lpDbnam, OCISvcCtx** pOCISvc, OCIEnv** pOCIEnv, ub4 dwConFlgs);
パラメータ
表4-2 OraMTSSvcGet()のパラメータ
パラメータ | IN/OUT | 説明 |
---|---|---|
|
IN |
Oracle Databaseに接続するためのユーザー名。 |
|
IN |
ユーザー名に対応するパスワード。 |
|
IN |
データベースに接続するためのネット・サービス名(Oracle Net ManagerまたはOracle Net Configuration Assistantで作成)。 |
|
OUT |
OCIサービス・コンテキスト・ハンドルへのポインタ。 |
|
OUT |
OCI環境ハンドルへのポインタ。 |
|
IN |
接続フラグ。使用可能な値は次のとおりです。
|
戻り値
プール済のOCI接続(OCIサービス・コンテキスト)の取得に成功すると、ORAMTSERR_NOERROR
が返されます。
使用上の注意
-
OraMTSSvcGet()
はプール済のOCI接続をコール側に返し、OCIを使用するデータベース・トランザクションが開始できるようにします。Microsoft Transaction Serverによって調整されるトランザクションにOCI接続を暗黙的に登録する場合は、OraMTSSvcGet()
を使用します。このタイプのトランザクションでは、Microsoft Transaction ServerがMS DTCコンポーネントを通じてトランザクションの作成、開始、管理、およびコミットの各フェーズを制御します。 -
OraMTSSvcGet()
は、Microsoft Transaction ServerトランザクションにOracle Databaseを登録せずに、接続プールを提供することもできます。そのためには、OraMTSSvcGet()
を次のように設定します。OraMTSSvcGet(...,ORAMTS_CFLG_NOIMPLICIT)
-
OraMTSSvcGet
()
を使用する場合は常に、OraMTSSvcRel
()
を使用して、終了時に接続を解放する必要があります。 -
SYSDBA
およびSYSOPER
として接続するときには、それぞれORAMTS_CFLG_SYSDBALOGN
フラグおよびORAMTS_CFLG_SYSOPRLOGN
フラグを使用します。 -
未登録の接続を
hr
/hr_password
アカウントで取得するには、OraMTSSvcGet()
を次のようにコールします。OraMTSSvcGet("hr", "hr_password", "oracle", &OCISvc, &OCIEnv, ORAMTS_CFLG_ALLDEFAULT | ORAMTS_CFLG_NOIMPLICIT);
-
OraMTSSvcGet()
では、ユーザー名(lpUname
)、パスワード(lpPsswd
)およびネット・サービス名構文(lpDbname
)を一緒にユーザー名引数に指定することはできません(hr/
hr_password
@prod_fin
など)。かわりに、コール側は前述の構文例のように、lpUname
、lpPsswd
およびlpDbname
を別々に指定する必要があります。ユーザー名およびパスワードにNULL
文字列を指定してOraMTSSvcGet()
をコールすると、接続のために外部認証(オペレーティング・システム認証)が使用されます。
4.3.4 OraMTSSvcRel()
プール済のOCI接続(OCIサービス・コンテキスト)を解放して接続プールに戻します。OraMTSSvcGet()
で取得した接続を解放するにはこの関数を使用します。
構文
DWORD OraMTSSvcRel(OCISvcCtx* OCISvc);
パラメータ
表4-3 OraMTSSvcRel()のパラメータ
パラメータ | IN/OUT | 説明 |
---|---|---|
|
IN |
プール済の接続のOCIサービス・コンテキスト |
戻り値
プール済のOCI接続の解放に成功すると、ORAMTSERR_NOERROR
が返されます。
使用上の注意
-
以前に
OraMTSSvcGet()
をコールして取得したプール済のOCI接続が解放されて、接続プールに戻ります。解放されて接続プールに戻ると、OCIサービス・コンテキスト、その環境ハンドルおよびすべての子ハンドルは無効になります。 -
非トランザクションのクライアント・コンポーネントでは、
OraMTSSvcGet(...,...,ORAMTS_CFLG_ALLDEFAULT)
を通じて取得した接続を解放してプールに戻す前に、OCITransCommit()
またはOCITransAbort()
を明示的にコールする必要があります。そうしないと、そのセッションで行ったすべての変更がロールバックされます。トランザクション・コンポーネントは、Microsoft Transaction Serverのオブジェクト・コンテキストに対してSetComplete
メソッドまたはSetAbort
メソッドを使用します。 -
リソースが登録されている場合、
OraMTSSvcGet(..., ...,ORAMTS_CFLG_NOIMPLICIT)
をコールして接続リソースを取得したコンポーネントは、まずリソースの登録を解除する必要があります。接続を明示的に登録した場合は、pTransaction->Commit()
またはpTransaction->Abort()
をコールします。それ以外の場合は、OCITransCommit()
またはOCITransAbort()
をコールしてから、接続を解放してプールに戻します。
4.3.5 OraMTSSvcEnlist()
MS DTCによって調整されるトランザクションにOCI接続を登録または登録解除します。このコールを使用して、プール済の接続を明示的に登録します。プールされていない接続は、OraMTSJoinTxn()
を使用して登録する必要があります。
構文
DWORD OraMTSSvcEnlist(
OCISvcCtx* OCISvc, OCIError* OCIErr, void* lpTrans, unsigned dwFlags);
パラメータ
表4-4 OraMTSSvcEnlist()のパラメータ
パラメータ | IN/OUT | 説明 |
---|---|---|
|
|
|
|
|
OCIエラー・ハンドル(無効)。 |
|
|
MS DTCが制御する登録先のトランザクションへのポインタ。 |
|
|
トランザクションへの登録に使用されるフラグ。 |
戻り値
成功すると、ORAMTSERR_NOERROR
が返されます。
使用上の注意
-
このコールを使用して、プール済の接続を明示的に登録または登録解除します。プールされていない接続の登録および登録解除には、
OraMTSSvcRel()
を使用します。 -
OraMTSSvcEnlist()
は、ORAMTS_CFLG_NOIMPLICIT
フラグを指定したOraMTSSvcGet()
を通じて以前に取得され、まだOraMTSSvcRel()
で解放されていないプール済のOCI接続を登録(または登録解除)します。プール済のOCI接続は、明示的に登録可能である必要があります。トランザクションが完了したら、次のようにトランザクション・ポインタとしてNULL
を渡し、OraMTSSvcEnlist()
の登録を解除します。OraMTSSvcEnlist (OCISvc, OCIErr, NULL, ORAMTS_ENFLG_DEFAULT)
OraMTSSvcRel()
を使用して、終了時に接続を解放します。 -
コール側は接続の割当て、接続の登録、処理の実行、接続の登録解除、接続の解放を行った後に、処理をコミットまたは終了する必要があります。
4.3.6 OraMTSSvcEnlistEx()
OCI接続またはサービス・コンテキストをMS DTCトランザクションに登録します。このコールは、プール済の接続の明示的な登録にのみ使用します。プールされていない接続は、OraMTSJoinTxn()
を使用して登録する必要があります。
構文
DWORD OraMTSSvcEnlistEx( OCISvcCtx* OCISvc,
OCIError* OCIErr, void* lpTrans, unsigned dwFlags, char* lpDBName);
パラメータ
表4-5 OraMTSSvcEnlistEx()のパラメータ
パラメータ | IN/OUT | 説明 |
---|---|---|
|
|
|
|
|
OCIエラー・ハンドル(無効)。 |
|
|
MS DTCが制御する登録先のトランザクションへのポインタ。 |
|
|
トランザクションへの登録に使用されるフラグ。 |
|
|
データベースに接続するためのネット・サービス名(Oracle Net ManagerまたはOracle Net Configuration Assistantで作成)。 |
戻り値
ORAMTSERR_ILLEGAL_OPER
が返されます。
使用上の注意
プール済の接続にはOraMTSSvcEnlistEx()
を、プールされていない接続にはOraMTSJoinTxn()
を使用します。
4.3.7 OraMTSEnlCtxGet()
プールされていないOCI接続の登録コンテキストを作成します。
構文
DWORD OraMTSEnlCtxGet(
text* lpUname, text* lpPsswd, text* lpDbnam, OCISvcCtx* pOCISvc, OCIError* pOCIErr, ub4 dwFlags, void** pCtxt);
パラメータ
表4-6 OraMTSEnlCtxGet()のパラメータ
パラメータ | IN/OUT | 説明 |
---|---|---|
|
|
Oracle Databaseに接続するためのユーザー名。 |
|
|
Oracle Databaseに接続するためのパスワード。 |
|
|
データベースに接続するためのネット・サービス名。 |
|
|
プールされていない接続のOCIサービス・コンテキスト。 |
|
|
OCIエラー・ハンドル |
|
|
登録フラグ。現在指定可能な値は |
|
|
作成される登録コンテキスト。 |
戻り値
成功すると、ORAMTSERR_NOERROR
が返されます。
使用上の注意
-
このコールでは、プールされていない接続の登録コンテキストが設定されます。このコールは、コール側がデータベースへのOCI接続を確立した直後に開始する必要があります。作成されたコンテキストは、
OraMTSJoinTxn()
のコールに渡されます。OCI接続を削除する前に、OraMTSEnlCtxRel()
をコールして、登録コンテキストを削除します。 -
コール側は、次の処理を実行する必要があります。
-
OCIを通じてプールされていない接続を割り当てます。
-
OraMTSEnlCtxGet()
をコールして、登録コンテキストを作成します。 -
OraMTSJoinTxn()
をコールして、接続を確立します。 -
データベース処理を実行します。
-
NULL
トランザクション・ポインタを指定したOraMTSJoinTxn()
をコールして、接続を登録解除します。 -
処理をコミットまたは終了します。
-
OraMTSEnlCtxRel()
をコールして、登録コンテキストを解放します。 -
プールされていないOCI接続を解放し、接続に関連付けられているOCI環境ハンドルを削除します。
-
4.3.8 OraMTSEnlCtxRel()
以前に設定したプールされていないOCI接続の登録コンテキストを破棄します。
構文
DWORD OraMTSEnlCtxRel(void* pCtxt);
パラメータ
表4-7 OraMTSEnlCtxRel()のパラメータ
パラメータ | IN/OUT | 説明 |
---|---|---|
|
IN |
破棄する登録コンテキスト |
戻り値
成功すると、ORAMTSERR_NOERROR
が返されます。
使用上の注意
-
プールされていないOCI接続を解放する前に、クライアントが
OraMTSEnlCtxRel()
をコールして、その接続に対して作成した登録コンテキストをすべて破棄する必要があります。登録コンテキストでは、接続のOCI環境ハンドルとは別に割り当てられたOCIハンドルが保持されます。そのため、環境ハンドルが関連の登録コンテキストに対して削除されないことが必要になります。
4.3.9 OraMTSJoinTxn()
プールされていないOCI接続をMS DTCトランザクションに登録します。
構文
DWORD OraMTSJoinTxn(void* pCtxt, void* pTrans);
パラメータ
表4-8 OraMTSJoinTxn()のパラメータ
パラメータ | IN | 説明 |
---|---|---|
|
|
OCI接続の登録コンテキスト |
|
|
MS DTCトランザクション・オブジェクトの参照 |
戻り値
成功すると、ORAMTSERR_NOERROR
が返されます。
使用上の注意
-
クライアントは、このコールをプールされていないOCI接続で使用して、接続をMS DTCによって調整されるトランザクションに登録します。クライアントは、MS DTCトランザクション・オブジェクトの参照とともに、OCI接続を表す登録コンテキストの広域参照を渡します。
pTrans
がNULL
の場合、OCI接続は現在登録されているMS DTCトランザクションから登録解除されます。すでに登録済のOCI接続を別のMS DTCトランザクションに登録できます。
4.3.10 OraMTSTransTest()
Microsoft Transaction Serverで開始されたトランザクションの内部で実行されているかどうかをテストします。
構文
BOOL OraMTSTransTest();
戻り値
Microsoft Transaction Server transactionトランザクション内で実行している場合は、true
が返されます。
使用上の注意
Microsoft Transaction Serverのトランザクション・コンポーネントは、OraMTSTransTest()
を使用して、あるコンポーネントがMicrosoft Transaction Serverトランザクションのコンテキスト内で実行されているかどうかを確認します。このコールでテストできるのは、Microsoft Transaction Serverによって開始されたトランザクションのみであることに注意してください。MS DTCを直接コールして開始したトランザクションは検出されません。
4.3.11 OraMTSOCIErrGet()
最後に実行したOraMTS
関数(通常はOraMTSSvcGet()
またはOraMTSJoinTxn()
)のOCIエラー・コードおよびメッセージ・テキストがある場合に、それを取り出します。
構文
BOOL OraMTSOCIErrGet(DWORD* dwErr, LPCHAR lpcEMsg, DWORD* lpdLen);
パラメータ
表4-9 OraMTSOCIErrGet()のパラメータ
パラメータ | IN/OUT | 説明 |
---|---|---|
|
|
エラー・コード |
|
|
エラー・メッセージがある場合、そのエラー・メッセージのバッファ |
|
|
メッセージの実際のバイト数に設定 |
戻り値
OCIエラーが発生すると、true
が戻されます。それ以外の場合はfalse
が返されます。true
が戻された場合、lpcEMsg
およびlpdLen
が有効で、スタッシュ・エラー・メッセージがあるときは、最大でlpdLen
バイトがlpcEMsg
にコピーされます。lpdLen
にはメッセージの実際のバイト数が設定されます。
使用上の注意
例4-2は、OraMTSOCIErrGet()
が、このスレッドで最後に実行したOraMTSSvc()
のOCIエラー・コードおよびOCIエラー・メッセージ・テキストがある場合に、それを取り出す方法を示しています。
例4-2 OCIエラー・コードおよびメッセージ・テキストの取出し
DWORD dwStat = OraMTSSvcGet("hr", "invalid_password", "fin_prod", "db", &mysvch, &myenvh, ORAMTS_CFLG_ALLDEFAULT); if (dwStat != ORAMTS_ERR_NOERROR) { DWORD dwOCIErr; char errBuf[MAX_PATH]; DWORD errBufLen = sizeof(effBuf); if (OraMTSOCIErrGet(&dwOCIErr, &errBuf, &errBufLen)) printf("OCIError %d: %s"\n); }
4.4 ODBCとMicrosoft Transaction Serverの統合の概要
このトピックでは、Oracle ODBCドライバをMicrosoft Transaction ServerおよびOracle Databaseとともに使用する方法について説明します。ODBCを正常に動作させるためにOCIコードを変更する必要はありません。
4.4.1 接続属性の設定
Oracle ODBC Driver 11.1またはMicrosoft Oracle ODBCドライバとともにMicrosoft Transaction Serverを使用するには、SQLSetConnectAttr
関数を使用して接続属性を設定し、ODBCコードでSQL_ATTR_ENLIST_IN_DTC
パラメータをコールします。これにより、接続プールおよび暗黙的なトランザクション・サポートが得られます。
4.4.2 Oracle ODBC Driverの使用
ODBC 3.0とともに配布されるODBCドライバ・マネージャは、接続プールをサポートするリソース・ディスペンサです。SQLSetConnectAttr(...,..., SQL_ATTR_ENLIST_IN_DTC)
コールを使用して、リリース11.1のOracle ODBCドライバとODBC 3.0ドライバ・マネージャを統合することにより、MS DTCによって調整されるトランザクションに対してODBC接続の登録および登録解除を行うことができます。
リリースのOracle ODBCドライバ11.1は、次のもので使用します。
関連項目:
詳細は、Microsoft Transaction ServerのSDKを参照してください。
4.4.3 Microsoft社製Oracle用ODBCドライバの使用
Oracle ODBCドライバのかわりに、Microsoft Oracle ODBCドライバを使用できます。Microsoftドライバを使用すると、Oracle Provider for OLE DBおよびOracle Data Provider for .NETとの統合はできませんので注意してください。また、Oracle ODBCドライバ、統合用のAPIサポート、またはOracleクライアントのサポート・サービスによるパフォーマンスの向上もありません。
Microsoft社製Oracle用ODBCドライバを有効にした後、さらに次の手順を実行して、Microsoft Oracle ODBCドライバを構成します。
関連項目:
Microsoft Oracle ODBCドライバを有効にする方法は、Microsoft Transaction Serverのオンライン・ヘルプの「MTSをOracleにアクセスできるように設定する」を参照してください。