分散トランザクションのサポート

SQL Server Native Client OLE DB プロバイダのコンシューマは、ITransactionJoin::JoinTransaction メソッドを使用して、Microsoft 分散トランザクション コーディネータ (MS DTC) によりコーディネートされる分散トランザクションに参加できます。

MS DTC が公開する COM オブジェクトを使用すると、クライアントは、さまざまなデータ ストアに対する複数の接続にまたがってコーディネートされるトランザクションを起動したり、このトランザクションに参加することができます。SQL Server Native Client OLE DB プロバイダのコンシューマは、MS DTC ITransactionDispenser インターフェイスを使用してトランザクションを起動します。ITransactionDispenserBeginTransaction メンバは、分散トランザクション オブジェクト上の参照を返します。この参照は、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 プロバイダでは、インターフェイスからのオプション オブジェクトが要求されます。このオプション オブジェクトの 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.

関連項目

概念