SQL Server Native Client OLE DB プロバイダー のコンシューマーは 、ITransactionJoin::JoinTransaction メソッドを使用して、Microsoft 分散トランザクション コーディネーター (MS DTC) によって調整された分散トランザクションに参加できます。
MS DTC は、クライアントがさまざまなデータ ストアへの複数の接続間で調整されたトランザクションを開始して参加できるようにする COM オブジェクトを公開します。 トランザクションを開始するために、SQL Server Native Client OLE DB プロバイダー コンシューマーは MS DTC ITransactionDispenser インターフェイスを 使用します。 ITransactionDispenser の BeginTransaction メンバーは、分散トランザクション オブジェクトの参照を返します。 この参照は、 JoinTransaction を使用して SQL Server Native Client OLE DB プロバイダーに渡されます。
MS DTC では、分散トランザクションでの非同期コミットと中止がサポートされます。 非同期トランザクションの状態に関する通知の場合、コンシューマーは ITransactionOutcomeEvents インターフェイスを実装し、インターフェイスを MS DTC トランザクション オブジェクトに接続します。
分散トランザクションの場合、SQL Server Native Client OLE DB プロバイダーは ITransactionJoin::JoinTransaction パラメーターを 次のように実装します。
| パラメーター | 説明 |
|---|---|
| punkTransactionCoord | MS DTC トランザクション オブジェクトへのポインター。 |
| IsoLevel | SQL Server Native Client OLE DB プロバイダーでは無視されます。 MS DTC で調整されたトランザクションの分離レベルは、コンシューマーが MS DTC からトランザクション オブジェクトを取得するときに決定されます。 |
| IsoFlags | 0 を指定する必要があります。 SQL Server Native Client OLE DB プロバイダーは、コンシューマーによって他の値が指定されている場合、XACT_E_NOISORETAINを返します。 |
| POtherOptions | NULL でない場合、SQL Server Native Client OLE DB プロバイダーはインターフェイスから options オブジェクトを要求します。 オプション オブジェクトの ulTimeout メンバーが 0 でない場合、SQL Server Native Client OLE DB プロバイダーはXACT_E_NOTIMEOUTを返します。 SQL Server Native Client OLE DB プロバイダーは 、szDescription メンバーの値を無視します。 |
この例では、MS DTC を使用してトランザクションを調整します。
// Interfaces used in the example.
IDBCreateSession* pIDBCreateSession = NULL;
ITransactionJoin* pITransactionJoin = NULL;
IDBCreateCommand* pIDBCreateCommand = NULL;
IRowset* pIRowset = NULL;
// Transaction dispenser and transaction from MS DTC.
ITransactionDispenser* pITransactionDispenser = NULL;
ITransaction* pITransaction = NULL;
HRESULT hr;
// Get the command creation interface for the session.
if (FAILED(hr = pIDBCreateSession->CreateSession(NULL,
IID_IDBCreateCommand, (IUnknown**) &pIDBCreateCommand)))
{
// Process error from session creation. Release any references and
// return.
}
// Get a transaction dispenser object from MS DTC and
// start a transaction.
if (FAILED(hr = DtcGetTransactionManager(NULL, NULL,
IID_ITransactionDispenser, 0, 0, NULL,
(void**) &pITransactionDispenser)))
{
// Process error message from MS DTC, release any references,
// and then return.
}
if (FAILED(hr = pITransactionDispenser->BeginTransaction(
NULL, ISOLATIONLEVEL_READCOMMITTED, ISOFLAG_RETAIN_DONTCARE,
NULL, &pITransaction)))
{
// Process error message from MS DTC, release any references,
// and then return.
}
// Join the transaction.
if (FAILED(pIDBCreateCommand->QueryInterface(IID_ITransactionJoin,
(void**) &pITransactionJoin)))
{
// Process failure to get an interface, release any references, and
// then return.
}
if (FAILED(pITransactionJoin->JoinTransaction(
(IUnknown*) pITransaction, 0, 0, NULL)))
{
// Process join failure, release any references, and then return.
}
// Get data into a rowset, then update the data. Functions are not
// illustrated in this example.
if (FAILED(hr = ExecuteCommand(pIDBCreateCommand, &pIRowset)))
{
// Release any references and return.
}
// If rowset data update fails, then terminate the transaction, else
// commit. The example doesn't retain the rowset.
if (FAILED(hr = UpdateDataInRowset(pIRowset, bDelayedUpdate)))
{
// Get error from update, then abort.
pITransaction->Abort(NULL, FALSE, FALSE);
}
else
{
if (FAILED(hr = pITransaction->Commit(FALSE, 0, 0)))
{
// Get error from failed commit.
//
// If a distributed commit fails, application logic could
// analyze failure and retry. In this example, terminate. The
// consumer must resolve this somehow.
pITransaction->Abort(NULL, FALSE, FALSE);
}
}
if (FAILED(hr))
{
// Update of data or commit failed. Release any references and
// return.
}
// Un-enlist from the distributed transaction by setting
// the transaction object pointer to NULL.
if (FAILED(pITransactionJoin->JoinTransaction(
(IUnknown*) NULL, 0, 0, NULL)))
{
// Process failure, and then return.
}
// Release any references and continue.