"ROLLBACK TRANSACTION named_transaction" 的意义是什么?(涉及IT技术)

6
我已经阅读了有关ROLLBACK TRANSACTIONnesting transactions的MSDN。 虽然我理解ROLLBACK TRANSACTION savepointname的意义,但我不理解ROLLBACK TRANSACTION transactionname
  1. transactionname只能在最外层事务中使用。
  2. ROLLBACK总是回滚整个事务“堆栈”,除非使用savepointname
基本上,根据我阅读的文档,在没有保存点的情况下,ROLLBACK会回滚所有事务(到@@TRANCOUNT=0)。 我唯一能看到的区别是这段代码:
如果在嵌套事务的任何级别执行使用外部事务名称的ROLLBACK TRANSACTION transaction_name语句,则所有嵌套事务都将回滚。如果在嵌套事务的任何级别上执行没有transaction_name参数的ROLLBACK WORK或ROLLBACK TRANSACTION语句,则会回滚所有嵌套事务,包括最外层的事务。从阅读中可以看出,这表明仅回滚命名事务(必须是最外层事务的名称),只会回滚嵌套事务。这将赋予回滚命名事务一些含义。因此,我设置了一个测试:
CREATE TABLE #TEMP (id varchar(50))

INSERT INTO #TEMP (id) VALUES ('NO')
SELECT id AS NOTRAN FROM #TEMP
SELECT @@TRANCOUNT AS NOTRAN_TRANCOUNT

BEGIN TRAN OUTERTRAN

INSERT INTO #TEMP (id) VALUES ('OUTER')
SELECT id AS OUTERTRAN FROM #TEMP
SELECT @@TRANCOUNT AS OUTERTRAN_TRANCOUNT

BEGIN TRAN INNERTRAN

INSERT INTO #TEMP (id) VALUES ('INNER')
SELECT id AS INNERTRAN FROM #TEMP
SELECT @@TRANCOUNT AS INNERTRAN_TRANCOUNT

ROLLBACK TRAN OUTERTRAN

IF @@TRANCOUNT > 0 ROLLBACK TRAN

SELECT id AS AFTERROLLBACK FROM #TEMP
SELECT @@TRANCOUNT AS AFTERROLLBACK_TRANCOUNT

DROP TABLE #TEMP

结果为(去除所有“X行受影响”的内容)

NOTRAN
--------------------------------------------------
NO

NOTRAN_TRANCOUNT
----------------
0

OUTERTRAN
--------------------------------------------------
NO
OUTER

OUTERTRAN_TRANCOUNT
-------------------
1

INNERTRAN
--------------------------------------------------
NO
OUTER
INNER

INNERTRAN_TRANCOUNT
-------------------
2

AFTERROLLBACK
--------------------------------------------------
NO

AFTERROLLBACK_TRANCOUNT
-----------------------
0

请注意,当我更改

时,输出结果 没有任何区别
ROLLBACK TRAN OUTERTRAN

简单地

ROLLBACK TRAN

那么,ROLLBACK TRANSACTION named_transaction 的意义是什么呢?

1个回答

5
保存点就像其名称所示:在日志序列中的“保存点”。日志序列始终是线性的。如果您回滚到保存点,您将回滚当前日志位置和保存点之间您的事务所做的所有操作。考虑您的例子:
LSN 1: BEGIN TRAN OUTERTRAN
LSN 2: INSERT INTO ...
LSN 3: BEGIN TRAN INNERTRAN
LSN 4: INSERT INTO ...
LSN 5: ROLLBACK TRAN OUTERTRAN

在日志序列号(LSN)1处创建OUTERTRAN保存点。第一个INSERT创建LSN 2。然后,INNERTRAN使用LSN 3创建保存点。第二个INSERT创建了新的LSN,即4。ROLLBACK OUTERTRAN相当于“回滚日志直到LSN 1”。您不能“跳过”日志的任何部分,因此必须回滚日志中的每个操作,直到达到LSN 1(即创建OUTERTRAN保存点时)。另一方面,如果在最后一个操作中发出ROLLBACK INNERTRAN,则引擎将回滚到LSN 3(INNERTRAN保存点插入日志的位置),从而保留LSN 1和LSN 2(即第一个INSERT)。有关保存点的实际示例,请参见异常处理和嵌套事务

好的,我明白你所做的。然而,我仍然想知道我的原始观点。我得到了保存点及其值,但是对于回滚事务(而不是保存点)名称仍然感到困惑。一个重要的注意事项是,显然您不能回滚内部事务。例如,ROLLBACK TRAN INNERTRAN会导致错误,“无法回滚INNERTRAN。找不到该名称的任何事务或保存点。”。这一点(关于禁止回滚命名嵌套事务)在我提到的文档链接中。 - Chris Simmons
3
要回滚到INNERTRAN,您需要使用语法“SAVE TRANSACTION INNERTRAN”,该语法创建了一个真正的保存点(而不是命名事务)。 命名事务主要用于恢复场景(“RESTORE WITH STOPAT OUTERTRAN”)。 - Remus Rusanu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接