Поддержка распределенных транзакций
SQL Server Native Client поставщиков OLE DB потребители могут использовать метод ITransactionJoin::JoinTransaction для участия в распределенной транзакции, координируемой координатором распределенных транзакций Майкрософт (MS DTC).
Службы MS DTC предоставляют доступ к COM-объектам, которые позволяют клиентам запускать и участвовать в координированных транзакциях через несколько соединений с различными хранилищами данных. Чтобы инициировать транзакцию, потребитель поставщика SQL Server Native Client OLE DB использует интерфейс MS DTC ITransactionDispenser. Элемент BeginTransaction интерфейса ITransactionDispenser возвращает ссылку на объект распределенной транзакции. Эта ссылка передается поставщику SQL Server Native Client OLE DB с помощью JoinTransaction.
Службы MS DTC поддерживают асинхронную фиксацию и прерывание распределенных транзакций. Для уведомления о состоянии асинхронных транзакций потребитель реализует интерфейс ITransactionOutcomeEvents и подключает интерфейс к объекту транзакции MS DTC.
Для распределенных транзакций поставщик SQL Server Native Client OLE DB реализует параметры ITransactionJoin::JoinTransaction следующим образом.
Параметр | Description |
---|---|
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 запрашивает объект options из интерфейса . Поставщик SQL Server Native Client OLE DB возвращает XACT_E_NOTIMEOUT, если элемент ulTimeout объекта параметров не равен нулю. Поставщик 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.