Freigeben über


Unterstützung verteilter Transaktionen in SQL Server Native Client

Gilt für: SQL Server Azure SQL-Datenbank Azure SQL verwaltete Instanz Azure Synapse Analytics Analytics Platform System (PDW)

SQL Server Native Client OLE DB-Anbieter-Verbraucher können die ITransactionJoin::JoinTransaction-Methode verwenden, um an einer verteilten Transaktion teilzunehmen, die von Microsoft Distributed Transaction Coordinator (MS DTC) koordiniert wird.

MS DTC macht COM-Objekte verfügbar, mit denen Clients koordinierte Transaktionen über mehrere Verbindungen zu verschiedenen Datenspeichern initiieren und daran teilnehmen können. Um eine Transaktion zu initiieren, verwendet der OLE DB-Anbieter von SQL Server Native Client die MS DTC ITransactionDispenser-Schnittstelle . Das BeginTransaction-Element von ITransactionDispenser gibt einen Verweis auf ein verteiltes Transaktionsobjekt zurück. Dieser Verweis wird mithilfe von JoinTransaction an den OLE DB-Anbieter des SQL Server Native Client übergeben.

MS DTC unterstützt asynchrone „Commit“- und „Abort“-Funktionen bei verteilten Transaktionen. Für Benachrichtigungen über den asynchronen Transaktionsstatus implementiert der Consumer die ITransactionOutcomeEvents-Schnittstelle und verbindet die Schnittstelle mit einem MS DTC-Transaktionsobjekt.

Für verteilte Transaktionen implementiert der OLE DB-Anbieter von SQL Server Native Client ITransactionJoin::JoinTransaction-Parameter wie folgt.

Parameter BESCHREIBUNG
punkTransactionCoord Ein Zeiger auf ein MS DTC-Transaktionsobjekt
IsoLevel Wird vom OLE DB-Anbieter des SQL Server Native Client ignoriert. Die Isolationsstufe für MS DTC-koordinierte Transaktionen wird festgelegt, wenn der Consumer vom MS DTC ein Transaktionsobjekt abruft.
IsoFlags Muss den Wert 0 (null) haben. Der OLE DB-Anbieter des SQL Server Native Client gibt XACT_E_NOISORETAIN zurück, wenn ein anderer Wert vom Consumer angegeben wird.
POtherOptions Wenn nicht NULL, fordert der OLE DB-Anbieter des SQL Server Native Client das Optionsobjekt von der Schnittstelle an. Der OLE DB-Anbieter des nativen SQL Server-Clients gibt XACT_E_NOTIMEOUT zurück, wenn das ulTimeout-Element des Optionsobjekts nicht null ist. Der OLE DB-Anbieter von SQL Server Native Client ignoriert den Wert des szDescription-Elements .

In diesem Beispiel werden Transaktionen mithilfe von MS DTC koordiniert.

// 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.

Weitere Informationen