ROLLBACK TRANSACTION (Transact-SQL)

将显式事务或隐性事务回滚到事务的起点或事务内的某个保存点。 可以使用 ROLLBACK TRANSACTION 清除自事务的起点或到某个保存点所做的所有数据修改。 它还释放由事务控制的资源。

适用范围:SQL Server(SQL Server 2008 至当前版本),Azure SQL Database(初始版本至当前版本)。

主题链接图标 Transact-SQL 语法约定

语法

ROLLBACK { TRAN | TRANSACTION } 
     [ transaction_name | @tran_name_variable
     | savepoint_name | @savepoint_variable ] 
[ ; ]

参数

  • transaction_name
    是为 BEGIN TRANSACTION 上的事务分配的名称。 transaction_name 必须符合标识符规则,但只使用事务名称的前 32 个字符。 嵌套事务时,transaction_name 必须是最外面的 BEGIN TRANSACTION 语句中的名称。 transaction_name 始终是区分大小写的,即使 SQL Server 实例不区分大小写也是如此。

  • @ tran_name_variable
    用户定义的、含有有效事务名称的变量的名称。 必须用 char、varchar、nchar 或 nvarchar 数据类型声明变量。

  • savepoint_name
    是 SAVE TRANSACTION 语句中的 savepoint_name。 savepoint_name 必须符合有关标识符的规则。 当条件回滚应只影响事务的一部分时,可使用 savepoint_name。

  • @ savepoint_variable
    是用户定义的、包含有效保存点名称的变量的名称。 必须用 char、varchar、nchar 或 nvarchar 数据类型声明变量。

错误处理

ROLLBACK TRANSACTION 语句不生成显示给用户的消息。 如果在存储过程或触发器中需要警告,请使用 RAISERROR 或 PRINT 语句。 RAISERROR 是用于指出错误的首选语句。

一般备注

不带 savepoint_name 和 transaction_name 的 ROLLBACK TRANSACTION 回滚到事务的起点。 嵌套事务时,该语句将所有内层事务回滚到最外面的 BEGIN TRANSACTION 语句。 在这两种情况下,ROLLBACK TRANSACTION 都将 @@TRANCOUNT 系统函数减小为 0。 ROLLBACK TRANSACTION savepoint_name 不减小 @@TRANCOUNT。

在由 BEGIN DISTRIBUTED TRANSACTION 显式启动或从本地事务升级而来的分布式事务中,ROLLBACK TRANSACTION 不能引用 savepoint_name。

在执行 COMMIT TRANSACTION 语句后不能回滚事务,但是 COMMIT TRANSACTION 与包含在要回滚的事务中的嵌套事务关联时除外。 在这种情况下,也将回滚嵌套事务,即使您对它发出了 COMMIT TRANSACTION。

在事务内允许有重复的保存点名称,但如果 ROLLBACK TRANSACTION 使用重复的保存点名称,则只回滚到最近的使用该保存点名称的 SAVE TRANSACTION。

互操作性

在存储过程中,不带 savepoint_name 和 transaction_name 的 ROLLBACK TRANSACTION 语句将所有语句回滚到最外面的 BEGIN TRANSACTION。 在存储过程中,ROLLBACK TRANSACTION 语句使 @@TRANCOUNT 在存储过程完成时的值不同于调用此存储过程时的 @@TRANCOUNT 值,并且生成信息性消息。 该信息不影响后面的处理。

如果在触发器中发出 ROLLBACK TRANSACTION:

  • 将回滚对当前事务中的那一点所做的所有数据修改,包括触发器所做的修改。

  • 触发器继续执行 ROLLBACK 语句之后的所有其余语句。 如果这些语句中的任意语句修改数据,则不回滚这些修改。 执行其余的语句不会激发嵌套触发器。

  • 在批处理中,不执行所有位于激发触发器的语句之后的语句。

当输入触发器时 @@TRANCOUNT 将以 1 递增,即使在自动提交模式下也是如此。 (系统将触发器视为隐含的嵌套事务处理。)

在存储过程中,ROLLBACK TRANSACTION 语句不影响调用该过程的批处理中的后续语句;将执行批处理中的后续语句。 在触发器中,ROLLBACK TRANSACTION 语句终止包含激发触发器的语句的批处理;不执行批处理中的后续语句。

ROLLBACK 对游标的影响由下面三个规则定义:

  1. 当 CURSOR_CLOSE_ON_COMMIT 设置为 ON 时,ROLLBACK 关闭但不释放所有打开的游标。

  2. 当 CURSOR_CLOSE_ON_COMMIT 设置为 OFF 时,ROLLBACK 不影响任何打开的同步 STATIC 或 INSENSITIVE 游标,也不影响已完全填充的异步 STATIC 游标。 将关闭但不释放任何其他类型的打开的游标。

  3. 终止批处理并生成内部回滚的错误将释放在包含错误声明的批处理中声明的所有游标。 将释放所有游标,而不考虑它们的类型或 CURSOR_CLOSE_ON_COMMIT 的设置情况。 这包括在错误批处理调用的存储过程中声明的游标。 在错误批处理之前的批处理中声明的游标遵循规则 1 和 2。 死锁错误便是此类错误的一个示例。 在触发器中发出的 ROLLBACK 语句也将自动生成此类错误。

锁定行为

指定了 savepoint_name 的 ROLLBACK TRANSACTION 语句释放在保存点之后获得的任何锁,但升级和转换除外。 这些锁不会被释放,而且不会转换回先前的锁模式。

权限

要求具有 public 角色的成员身份。

示例

以下示例显示了回滚已命名事务的效果。

USE tempdb;
GO
CREATE TABLE ValueTable ([value] int;)
GO

DECLARE @TransactionName varchar(20) = 'Transaction1';

--The following statements start a named transaction,
--insert two rows, and then roll back
--the transaction named in the variable @TransactionName.
--Another statement outside of the named transaction inserts two rows.
--The query returns the results of the previous statements.

BEGIN TRAN @TransactionName
       INSERT INTO ValueTable VALUES(1), (2);
ROLLBACK TRAN @TransactionName;

INSERT INTO ValueTable VALUES(3),(4);

SELECT [value] FROM ValueTable;

DROP TABLE ValueTable;

--Results
--value
-------------
--3
--4

请参阅

参考

BEGIN DISTRIBUTED TRANSACTION (Transact-SQL)

BEGIN TRANSACTION (Transact-SQL)

COMMIT TRANSACTION (Transact-SQL)

COMMIT WORK (Transact-SQL)

ROLLBACK WORK (Transact-SQL)

SAVE TRANSACTION (Transact-SQL)