支持本地事务

适用于:SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics Analytics Platform System (PDW)

下载 OLE DB 驱动程序

会话分隔 OLE DB Driver for SQL Server 本地事务的事务范围。 当 OLE DB Driver for SQL Server 根据使用者指示向连接的 SQL Server 实例提交请求时,该请求构成 OLE DB Driver for SQL Server 的工作单元。 本地事务始终在一个 OLE DB Driver for SQL Server 会话中包装一个或多个工作单元。

使用默认的适用于 SQL Server 的 OLE DB 驱动程序自动提交模式,将一个工作单元视为本地事务的范围。 只能有一个单元参与本地事务。 创建会话时,OLE DB Driver for SQL Server 开始该会话的事务。 在成功完成工作单元之后提交工作。 如果失败,则回滚任何已开始的任何工作,并向使用者报告错误。 无论哪种情况,适用于 SQL Server 的 OLE DB 驱动程序都会为会话开始新的本地事务,以便在一个事务中执行所有工作。

适用于 SQL Server 的 OLE DB 驱动程序使用者可使用 ITransactionLocal 接口对本地事务范围进行更精确的控制 。 当使用者会话启动事务时,事务起点和最终 Commit 或 Abort 方法调用之间的所有会话工作单元都被视为原子单元 。 当使用者指示开始事务时,OLE DB Driver for SQL Server 将隐式执行此操作。 如果使用者未请求保持,该会话恢复为父事务级行为,通常为自动提交模式。

OLE DB Driver for SQL Server 支持以下 ITransactionLocal::StartTransaction 参数。

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

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] OLE DB Driver for SQL Server 针对任何非零值返回错误。
pOtherOptions[in] 如果不是 NULL,OLE DB Driver for SQL Server 将从该接口请求选项对象。 如果 options 对象的 ulTimeout 成员不为零,OLE DB Driver for SQL Server 返回 XACT_E_NOTIMEOUT。 OLE DB Driver for SQL Server 忽略 szDescription 成员的值。
pulTransactionLevel[out] 如果不为 NULL,OLE DB Driver for SQL Server 将返回事务的嵌套级别。

对于本地事务,OLE DB Driver for SQL Server 按如下方式实现 ITransaction::Abort 参数。

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

对于本地事务,OLE DB Driver for SQL Server 按如下方式实现 ITransaction::Commit 参数。

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

会话上的适用于 SQL Server 的 OLE DB 驱动程序行集根据行集属性 DBPROP_ABORTPRESERVE 和 DBPROP_COMMITPRESERVE 的值保留在本地提交或中止操作中。 默认情况下,这些属性均为 VARIANT_FALSE,并且在执行中止或提交操作之后,将丢失该会话上的所有适用于 SQL Server 的 OLE DB 驱动程序行集。

OLE DB Driver for SQL Server 不实现 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.  

另请参阅

中的
使用快照隔离