6

我已经阅读了 MSDN 关于ROLLBACK TRANSACTION嵌套事务。虽然我看到了点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

4

1 回答 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 相当于'ROLLBACK log until the LSN 1'。您不能“跳过”日志的某些部分,因此您必须回滚日志中的每个操作,直到命中 LSN 1(创建保存点 OUTERTRAN 时)。

另一方面,如果在最后一次操作中发出 ROLLBACK INNERTRAN 引擎将回滚直到 LSN 3(在日志中插入了“INNERTRAN”保存点),从而保留 LSN 1 和 LSN 2(即第一个 INSERT )。

有关保存点的实际示例,请参阅异常处理和嵌套事务

于 2009-11-28T21:14:42.970 回答