支持 SQL Server Native Client 中的分布式事务

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics 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.

另请参阅