분산 트랜잭션 지원
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 인터페이스를 사용하여 트랜잭션을 시작합니다. ITransactionDispenser의 BeginTransaction 멤버는 분산 트랜잭션 개체에 대한 참조를 반환합니다. 이 참조는 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이어야 합니다. 소비자가 0 이외의 값을 지정하면 SQL Server Native Client OLE DB 공급자가 XACT_E_NOISORETAIN을 반환합니다. |
POtherOptions |
NULL이 아니면 SQL Server Native Client OLE DB 공급자는 인터페이스에서 옵션 개체를 요청합니다. SQL Server Native Client OLE DB 공급자는 옵션 개체의 ulTimeout 멤버가 0이 아닌 경우 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.