支持 SQL Server Native Client 中的本地事务

适用于:SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics Analytics 平台系统(PDW)

会话分隔 SQL Server Native Client OLE DB 提供程序本地事务的事务范围。 当 SQL Server Native Client OLE DB 访问接口向连接的 SQL Server 实例提交请求时,该请求构成了 SQL Server Native Client OLE DB 访问接口的工作单元。 本地事务始终在单个 SQL Server Native Client OLE DB 访问接口会话上包装一个或多个工作单元。

使用默认的 SQL Server Native Client OLE DB 提供程序自动提交模式,单个工作单元被视为本地事务的范围。 只能有一个单元参与本地事务。 创建会话时,SQL Server Native Client OLE DB 访问接口将开始会话的事务。 在成功完成工作单元之后提交工作。 如果失败,则回滚任何已开始的任何工作,并向使用者报告错误。 在任一情况下,SQL Server Native Client OLE DB 提供程序都会为会话启动新的本地事务,以便所有工作都在事务中执行。

SQL Server Native Client OLE DB 访问接口可以使用 ITransactionLocal 接口更准确地控制本地事务范围。 当使用者会话启动事务时,事务起点和最终 Commit 或 Abort 方法调用之间的所有会话工作单元都被视为原子单元 。 当使用者定向到该事务时,SQL Server Native Client OLE DB 提供程序会隐式启动事务。 如果使用者未请求保持,该会话恢复为父事务级行为,通常为自动提交模式。

SQL Server Native Client OLE DB 提供程序支持 ITransactionLocal::StartTransaction 参数,如下所示。

参数 说明
isoLevel[in] 用于该事务的隔离级别。 在本地事务中,SQL Server Native Client OLE DB 访问接口支持以下各项:

ISOLATIONLEVEL_UNSPECIFIED

ISOLATIONLEVEL_CHAOS

ISOLATIONLEVEL_READUNCOMMITTED

ISOLATIONLEVEL_READCOMMITTED

ISOLATIONLEVEL_REPEATABLEREAD

ISOLATIONLEVEL_CURSORSTABILITY

ISOLATIONLEVEL_REPEATABLEREAD

ISOLATIONLEVEL_SERIALIZABLE

ISOLATIONLEVEL_ISOLATED

ISOLATIONLEVEL_SNAPSHOT



注意:从 SQL Server 2005 (9.x) 开始,ISOLATIONLEVEL_SNAPSHOT 对 isoLevel 参数有效,而不管是否对数据库启用了版本支持 。 但是,如果用户尝试执行语句,并且未启用版本支持和/或数据库不为只读,则将发生错误。 此外,如果在连接到 SQL Server 2005 (9.x) 以前的 SQL Server 版本时将 ISOLATIONLEVEL_SNAPSHOT 指定为 isoLevel,将发生 XACT_E_ISOLATIONLEVEL 错误。
isoFlags[in] SQL Server Native Client OLE DB 访问接口返回除零以外的任何值的错误。
pOtherOptions[in] 如果不是 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 成员的值
pulTransactionLevel[out] 如果不是 NULL,则 SQL Server Native Client OLE DB 访问接口返回事务的嵌套级别。

对于本地事务,SQL Server Native Client OLE DB 提供程序实现 ITransaction::Abort 参数,如下所示。

参数 说明
pboidReason[in] 忽略(如果设置)。 可以安全地为 NULL。
fRetaining[in] 当该参数为 TRUE 时,将针对会话隐式开始新的事务。 事务必须由使用者提交或中止。 如果为 FALSE,SQL Server Native Client OLE DB 访问接口将还原为会话的自动提交模式。
fAsync[in] SQL Server Native Client OLE DB 访问接口不支持异步中止。 如果值不为 FALSE,SQL Server Native Client OLE DB 访问接口将返回XACT_E_NOTSUPPORTED。

对于本地事务,SQL Server Native Client OLE DB 提供程序实现 ITransaction::Commit 参数,如下所示。

参数 说明
fRetaining[in] 当该参数为 TRUE 时,将针对会话隐式开始新的事务。 事务必须由使用者提交或中止。 如果为 FALSE,SQL Server Native Client OLE DB 访问接口将还原为会话的自动提交模式。
grfTC[in] SQL Server Native Client OLE DB 访问接口不支持异步返回和第一阶段返回。 SQL Server Native Client OLE DB 访问接口返回除XACTTC_SYNC以外的任何值XACT_E_NOTSUPPORTED。
grfRM[in] 必须为 0。

会话上的 SQL Server Native Client OLE DB 访问接口行集将保留在本地提交或中止操作上,具体取决于行集属性的值DBPROP_ABORTPRESERVE和DBPROP_COMMITPRESERVE。 默认情况下,这些属性都是VARIANT_FALSE,会话上的所有 SQL Server Native Client OLE DB 提供程序行集在中止或提交操作后都会丢失。

SQL Server Native Client OLE DB 访问接口不实现 ITransactionObject 接口。 尝试检索接口上的引用的使用者将返回 E_NOINTERFACE。

此示例使用 ITransactionLocal 。

// Interfaces used in the example.  
IDBCreateSession*   pIDBCreateSession   = NULL;  
ITransaction*       pITransaction       = NULL;  
IDBCreateCommand*   pIDBCreateCommand   = NULL;  
IRowset*            pIRowset            = NULL;  
  
HRESULT             hr;  
  
// Get the command creation and local transaction interfaces for the  
// session.  
if (FAILED(hr = pIDBCreateSession->CreateSession(NULL,  
     IID_IDBCreateCommand, (IUnknown**) &pIDBCreateCommand)))  
    {  
    // Process error from session creation. Release any references and  
    // return.  
    }  
  
if (FAILED(hr = pIDBCreateCommand->QueryInterface(IID_ITransactionLocal,  
    (void**) &pITransaction)))  
    {  
    // Process error. Release any references and return.  
    }  
  
// Start the local transaction.  
if (FAILED(hr = ((ITransactionLocal*) pITransaction)->StartTransaction(  
    ISOLATIONLEVEL_REPEATABLEREAD, 0, NULL, NULL)))  
    {  
    // Process error from StartTransaction. Release any references and  
    // 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 terminate.  
    pITransaction->Abort(NULL, FALSE, FALSE);  
    }  
else  
    {  
    if (FAILED(hr = pITransaction->Commit(FALSE, XACTTC_SYNC, 0)))  
        {  
        // Get error from failed commit.  
        }  
    }  
  
if (FAILED(hr))  
    {  
    // Update of data or commit failed. Release any references and  
    // return.  
    }  
  
// Release any references and continue.  

另请参阅

中的
使用快照隔离