控制事务(数据库引擎)

应用程序主要通过指定事务启动和结束的时间来控制事务。可以使用 Transact-SQL 语句或数据库应用程序编程接口 (API) 函数来指定这些时间。系统还必须能够正确处理那些在事务完成之前便终止事务的错误。

默认情况下,事务按连接级别进行管理。在一个连接上启动一个事务后,该事务结束之前,在该连接上执行的所有 Transact-SQL 语句都是该事务的一部分。但是,在多个活动的结果集 (MARS) 会话中,Transact-SQL 显式或隐式事务将变成批范围的事务,这种事务按批处理级别进行管理。当批处理完成时,如果批范围的事务还没有提交或回滚,SQL Server 将自动回滚该事务。

启动事务

使用 API 函数和 Transact-SQL 语句,可以在 SQL Server 数据库引擎实例中将事务作为显式、自动提交或隐式事务来启动。在 MARS 会话中,Transact-SQL 显式和隐式事务将变成批范围的事务。

  • 显式事务
    通过 API 函数或通过发出 Transact-SQL BEGIN TRANSACTION 语句来显式启动事务。

  • 自动提交事务
    数据库引擎的默认模式。每个单独的 Transact-SQL 语句都在其完成后提交。不必指定任何语句来控制事务。

  • 隐式事务
    通过 API 函数或 Transact-SQL SET IMPLICIT_TRANSACTIONS ON 语句,将隐性事务模式设置为打开。下一个语句自动启动一个新事务。当该事务完成时,下一个 Transact-SQL 语句又将启动一个新事务。

  • 批范围的事务
    只适用于多个活动的结果集 (MARS),在 MARS 会话中启动的 Transact-SQL 显式或隐式事务将变成批范围的事务。当批处理完成时,如果批范围的事务还没有提交或回滚,SQL Server 将自动回滚该事务。

事务模式按连接级别进行管理。一个连接的事务模式发生变化对任何其他连接的事务模式没有影响。

结束事务

您可以使用 COMMIT 或 ROLLBACK 语句,或者通过 API 函数来结束事务。

  • COMMIT
    如果事务成功,则提交。COMMIT 语句保证事务的所有修改在数据库中都永久有效。COMMIT 语句还释放事务使用的资源(例如,锁)。

  • ROLLBACK
    如果事务中出现错误,或用户决定取消事务,则回滚该事务。ROLLBACK 语句通过将数据返回到它在事务开始时所处的状态,来取消事务中的所有修改。ROLLBACK 还释放事务占用的资源。

注意注意

在为支持多个活动的结果集 (MARS) 而建立的连接中,只要还有待执行的请求,就无法提交通过 API 函数启动的显式事务。如果在未完成的操作还在运行时尝试提交此类事务,将导致出现错误。

指定事务边界

可以使用 Transact-SQL 语句或 API 函数和方法来确定数据库引擎事务启动和结束的时间。

  • Transact-SQL 语句
    可以使用 BEGIN TRANSACTION、COMMIT TRANSACTION、COMMIT WORK、ROLLBACK TRANSACTION、ROLLBACK WORK 和 SET IMPLICIT_TRANSACTIONS 语句来描述事务。这些语句主要用于 DB 库应用程序和 Transact-SQL 脚本(如使用 osql 命令提示实用工具运行的脚本)中。

  • API 函数和方法
    数据库 API(如 ODBC、OLE DB、ADO 和 .NET Framework SQLClient 命名空间)包含用于描述事务的函数或方法。这些是数据库引擎应用程序中用于控制事务的主要机制。

每个事务都必须只由其中一种方法管理。在对同一事务使用两种方法会导致出现不确定的结果。例如,不应先使用 ODBC API 函数启动一个事务,再使用 Transact-SQL COMMIT 语句完成该事务。这样将无法向 SQL Server ODBC 驱动程序通知已提交该事务。在这种情况下,应使用 ODBC SQLEndTran 函数结束该事务。

事务处理过程中的错误

如果某个错误使事务无法成功完成,SQL Server 会自动回滚该事务,并释放该事务占用的所有资源。如果客户端与数据库引擎实例的网络连接中断了,那么当网络向实例通知该中断后,该连接的所有未完成事务均会被回滚。如果客户端应用程序失败或客户端计算机崩溃或重新启动,也会中断连接,而且当网络向数据库引擎实例通知该中断后,该实例会回滚所有未完成的连接。如果客户端从该应用程序注销,所有未完成的事务也会被回滚。

如果批中出现运行时语句错误(如违反约束),那么数据库引擎中的默认行为是只回滚产生该错误的语句。可以使用 SET XACT_ABORT 语句更改此行为。在执行 SET XACT_ABORT ON 语句后,任何运行时语句错误都将导致自动回滚当前事务。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。有关详细信息,请参阅 SET XACT_ABORT (Transact-SQL)

出现错误时,纠正操作(COMMIT 或 ROLLBACK)应包括在应用程序代码中。一种处理错误(包括那些事务中的错误)的有效工具是 Transact-SQL TRY...CATCH 构造。有关包括事务的示例的详细信息,请参阅在 Transact-SQL 中使用 TRY...CATCHTRY...CATCH (Transact-SQL)