Prise en charge des transactions distribuées

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

MS DTC expose les objets COM qui permettent aux clients d'initialiser des transactions coordonnées et d'y participer sur plusieurs connexions à diverses banques de données. Pour initialiser une transaction, le consommateur du fournisseur OLE DB SQL Server Native Client 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 passée 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 toute autre valeur est spécifiée par le consommateur.

POtherOptions

Si la valeur est différente de NULL, le fournisseur OLE DB SQL Server Native Client demande l'objet d'options de l'interface. Le fournisseur OLE DB SQL Server Native Client retourne XACT_E_NOTIMEOUT si le membre ulTimeout de l'objet d'options est différent de zéro. Le fournisseur OLE DB SQL Server Native Client ignore la valeur du membre szDescription.

Cet exemple coordonne la transaction à 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

Concepts