Obsługa transakcji rozproszonych

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

pobierz sterownik OLE DB

Konsumenci OLE DB Driver for SQL Server mogą korzystać z metody ITransactionJoin::JoinTransaction, aby uczestniczyć w rozproszonej transakcji koordynowanej przez Microsoft Distributed Transaction Coordinator (MS DTC).

MS DTC udostępnia obiekty COM, które pozwalają klientom inicjować i uczestniczyć w skoordynowanych transakcjach przez wiele połączeń z różnymi magazynami danych. Aby rozpocząć transakcję, konsument OLE DB Driver for SQL Server korzysta z interfejsu MS DTC ITransactionDispenser. Członek BeginTransaction w ITransactionDispenser zwraca referencję do rozproszonego obiektu transakcji. To odwołanie jest przekazywane do sterownika OLE DB Driver for SQL Server za pomocą JoinTransaction.

MS DTC obsługuje asynchroniczne zatwierdzanie i przerwanie na transakcjach rozproszonych. Aby powiadomić o statusie transakcji asynchronicznej, konsument implementuje interfejs ITransactionOutcomeEvents i łączy ten interfejs z obiektem transakcyjnym MS DTC.

Dla transakcji rozproszonych sterownik OLE DB Driver for SQL Server implementuje parametry ITransactionJoin::JoinTransaction w następujący sposób.

Parameter Description
punkTransactionCoord Wskaźnik do obiektu transakcyjnego MS DTC.
IsoLevel Zignorowany przez sterownik OLE DB Driver for SQL Server. Poziom izolacji dla transakcji koordynowanych przez MS DTC jest określany, gdy konsument nabywa obiekt transakcyjny z MS DTC.
IsoFlags Musi mieć wartość 0. OLE DB Driver for SQL Server zwraca XACT_E_NOISORETAIN jeśli konsument określi inną wartość.
POtherOptions Jeśli nie NULL, sterownik OLE DB dla SQL Server żąda obiektu opcji z interfejsu. Sterownik OLE DB dla SQL Server zwraca XACT_E_NOTIMEOUT, jeśli członek ulTimeout obiektu opcji nie jest zerowy. Sterownik OLE DB dla SQL Server ignoruje wartość członka szDescription .

Ten przykład koordynuje transakcję za pomocą 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.