Compartilhar via


Suporte a transações distribuídas no SQL Server Native Client

Aplica-se a: SQL Server Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure PDW (Sistema de Plataforma de Análise) do Azure Synapse Analytics

Os consumidores do provedor OLE DB do SQL Server Native Client podem usar o método ITransactionJoin::JoinTransaction para participar de uma transação distribuída coordenada pelo MS DTC (Coordenador de Transações Distribuídas da Microsoft).

O MS DTC expõe objetos COM que permitem que os clientes iniciem e participem de transações coordenadas em várias conexões com vários armazenamentos de dados. Para iniciar uma transação, o consumidor do provedor OLE DB do SQL Server Native Client usa a interface ITransactionDispenser do MS DTC. O membro BeginTransaction de ITransactionDispenser retorna uma referência a um objeto de transação distribuída. Essa referência é passada para o provedor OLE DB do SQL Server Native Client usando JoinTransaction.

O MS DTC dá suporte à confirmação e à anulação assíncronas de transações distribuídas. Para obter a notificação do status da transação assíncrona, o consumidor implementa a interface ITransactionOutcomeEvents e a conecta a um objeto de transação do MS DTC.

Para transações distribuídas, o provedor OLE DB do SQL Server Native Client implementa os parâmetros ITransactionJoin::JoinTransaction da seguinte maneira.

Parâmetro DESCRIÇÃO
punkTransactionCoord Um ponteiro para um objeto de transação do MS DTC.
IsoLevel Ignorado pelo provedor OLE DB do SQL Server Native Client. O nível de isolamento para transações coordenadas pelo MS DTC é determinado quando o consumidor faz a aquisição de um objeto de transação do MS DTC.
IsoFlags Deve ser 0. O provedor OLE DB do SQL Server Native Client retornará XACT_E_NOISORETAIN se qualquer outro valor for especificado pelo consumidor.
POtherOptions Se não for NULL, o provedor OLE DB do SQL Server Native Client solicitará o objeto options da interface. O provedor OLE DB do SQL Server Native Client retornará XACT_E_NOTIMEOUT se o membro ulTimeout do objeto de opções não for zero. O provedor OLE DB do SQL Server Native Client ignora o valor do membro szDescription .

Este exemplo coordena transações usando o 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.

Confira também