SQL Server Native Client에서 분산 트랜잭션 지원

적용 대상:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics AnalyticsPlatform System(PDW)

SQL Server Native Client OLE DB 공급자 소비자는 ITransactionJoin::JoinTransaction 메서드를 사용하여 MS DTC(Microsoft Distributed Transaction Coordinator)가 조정한 분산 트랜잭션에 참여할 수 있습니다.

MS DTC는 클라이언트가 다양한 데이터 저장소에 대한 여러 연결을 통해 조정된 트랜잭션을 시작하고 참여할 수 있도록 하는 COM 개체를 노출합니다. 트랜잭션을 시작하기 위해 SQL Server Native Client OLE DB 공급자 소비자는 MS DTC ITransactionDispenser 인터페이스를 사용합니다. ITransactionDispenserBeginTransaction 멤버는 분산 트랜잭션 개체에 대한 참조를 반환합니다. 이 참조는 JoinTransaction을 사용하여 SQL Server Native Client OLE DB 공급자에 전달됩니다.

MS DTC는 분산 트랜잭션에서 비동기 커밋 및 중단을 지원합니다. 비동기 트랜잭션 상태에 대한 알림을 위해 소비자는 ITransactionOutcomeEvents 인터페이스를 구현하고 인터페이스를 MS DTC 트랜잭션 개체에 연결합니다.

분산 트랜잭션의 경우 SQL Server Native Client OLE DB 공급자는 다음과 같이 ITransactionJoin::JoinTransaction 매개 변수를 구현합니다.

매개 변수 설명
punkTransactionCoord MS DTC 트랜잭션 개체에 대한 포인터입니다.
IsoLevel SQL Server Native Client OLE DB 공급자가 무시합니다. MS DTC 조정 트랜잭션의 격리 수준은 소비자가 MS DTC에서 트랜잭션 개체를 획득할 때 결정됩니다.
IsoFlags 0이어야 합니다. 소비자가 지정한 다른 값이 있으면 SQL Server Native Client OLE DB 공급자는 XACT_E_NOISORETAIN 반환합니다.
POtherOptions NULL이 아닌 경우 SQL Server Native Client OLE DB 공급자는 인터페이스에서 옵션 개체를 요청합니다. 옵션 개체의 ulTimeout 멤버가 0이 아닌 경우 SQL Server Native Client OLE DB 공급자는 XACT_E_NOTIMEOUT 반환합니다. SQL Server Native Client OLE DB 공급자는 szDescription 멤버의 값을 무시합니다.

다음은 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.

참고 항목