Prise en charge des transactions distribuées dans SQL Server Native Client

S’applique à :SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

SQL Server Native Client consommateurs du fournisseur OLE DB peuvent utiliser la méthode ITransactionJoin::JoinTransaction pour participer à une transaction distribuée coordonnée par Microsoft Distributed Transaction Coordinator (MS DTC).

MS DTC expose des objets COM qui permettent aux clients d’initier et de participer à des transactions coordonnées entre plusieurs connexions à différents magasins de données. Pour lancer une transaction, le consommateur SQL Server Native Client fournisseur OLE DB utilise l’interface MS DTC ITransactionDispenser. Le membre BeginTransaction de ITransactionDispenser retourne une référence sur un objet de transaction distribué. Cette référence est transmise au fournisseur OLE DB SQL Server Native Client à l’aide de JoinTransaction.

MS DTC prend en charge l'abandon et la validation asynchrones sur les transactions distribuées. Pour la notification sur l’état de transaction asynchrone, le consommateur implémente l’interface ITransactionOutcomeEvents et connecte l’interface à un objet de transaction MS DTC.

Pour les transactions distribuées, le fournisseur OLE DB SQL Server Native Client implémente les paramètres ITransactionJoin::JoinTransaction comme suit.

Paramètre Description
punkTransactionCoord Pointeur vers un objet de transaction MS DTC.
IsoLevel Ignoré par le fournisseur OLE DB SQL Server Native Client. Le niveau d'isolation pour les transactions coordonnées MS DTC est déterminé lorsque le consommateur acquiert un objet de transaction à partir de MS DTC.
IsoFlags Doit être égal à 0. Le fournisseur OLE DB SQL Server Native Client retourne XACT_E_NOISORETAIN si une autre valeur est spécifiée par le consommateur.
POtherOptions Si ce n’est pas NULL, le fournisseur OLE DB SQL Server Native Client demande l’objet options à partir de l’interface. Le fournisseur OLE DB SQL Server Native Client retourne XACT_E_NOTIMEOUT si le membre ulTimeout de l’objet options n’est pas zéro. Le fournisseur OLE DB SQL Server Native Client ignore la valeur du membre szDescription.

Cet exemple montre comment coordonner les transactions à l’aide de 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.

Voir aussi