Stöd för distribuerade transaktioner

gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics

Ladda ned OLE DB-drivrutins

OLE DB Driver for SQL Server-konsumenter kan använda metoden ITransactionJoin::JoinTransaction för att delta i en distribuerad transaktion koordinerad av Microsoft Distributed Transaction Coordinator (MS DTC).

MS DTC exponerar COM-objekt som gör det möjligt för klienter att initiera och delta i koordinerade transaktioner över flera anslutningar till olika datalagre. För att initiera en transaktion använder OLE DB Driver for SQL Server consumer MS DTC ITransactionDispenser-gränssnittet. BeginTransaction-medlemmen i ITransactionDispenser returnerar en referens på ett distribuerat transaktionsobjekt. Denna referens skickas till OLE DB Driver for SQL Server med hjälp av JoinTransaction.

MS DTC stöder asynkron commit och abort på distribuerade transaktioner. För avisering om asynkron transaktionsstatus implementerar konsumenten ITransactionOutcomeEvents-gränssnittet och kopplar gränssnittet till ett MS DTC-transaktionsobjekt.

För distribuerade transaktioner implementerar OLE DB Driver for SQL Server ITransactionJoin::JoinTransaction-parametrar enligt följande.

Parameter Description
punkTransaktionCoord En pekare till ett MS DTC-transaktionsobjekt.
IsoLevel Ignoreras av OLE DB Driver'n för SQL Server. Isoleringsnivån för MS DTC-koordinerade transaktioner bestäms när konsumenten förvärvar ett transaktionsobjekt från MS DTC.
IsoFlags Måste vara 0. OLE DB Driver for SQL Server returnerar XACT_E_NOISORETAIN om något annat värde anges av konsumenten.
POtherOptions Om det inte är NULL, begär OLE DB-drivrutinen för SQL Server optionsobjektet från gränssnittet. OLE DB-drivrutinen för SQL Server returnerar XACT_E_NOTIMEOUT om optionsobjektets ulTimeout-medlem inte är noll. OLE DB-drivrutinen för SQL Server ignorerar värdet på medlemmen szDescription .

Detta exempel koordinerar transaktioner genom att använda 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.