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