支援 SQL Server Native Client 中的分散式交易
適用於:SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體 Azure Synapse Analytics Analytics Platform System (PDW)
SQL Server Native Client OLE DB 提供者取用者可以使用 ITransactionJoin::JoinTransaction 方法來參與由 Microsoft分散式交易協調器 (MS DTC) 協調的分散式交易。
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。 如果取用者指定任何其他值,SQL Server Native Client OLE DB 提供者會傳回XACT_E_NOISORETAIN。 |
POtherOptions | 如果不是 NULL,SQL Server Native Client OLE DB 提供者會從 介面要求 options 物件。 如果 options 物件的 ulTimeout 成員不是零,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.