"ROLLBACK TRANSACTION named_transaction"有什么意义?

Chr*_*ons 6 t-sql transactions rollback sql-server-2008

我已经通过MSDN阅读了ROLLBACK TRANSACTION嵌套事务.虽然我明白了ROLLBACK TRANSACTION savepointname,我不明白ROLLBACK TRANSACTION transactionname.

  1. 它只transactionname在最外面的事务处理时才有效
  2. ROLLBACK 总是回滚整个事务"堆栈",除非是 savepointname

基本上,当我阅读文档时,除了保存点之外,ROLLBACK回滚所有事务(to @@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
Run Code Online (Sandbox Code Playgroud)

导致(所有"X行受影响"的东西被移除)

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

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

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

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

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

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

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

AFTERROLLBACK_TRANCOUNT
-----------------------
0
Run Code Online (Sandbox Code Playgroud)

请注意,更改时输出没有区别

ROLLBACK TRAN OUTERTRAN
Run Code Online (Sandbox Code Playgroud)

简单地说

ROLLBACK TRAN
Run Code Online (Sandbox Code Playgroud)

那有什么意义呢?ROLLBACK TRANSACTION named_transaction

Rem*_*anu 5

保存点与名称完全相同:日志序列中的"保存点".日志序列始终是线性的.如果你回滚到一个保存点,你回滚一切你当前日志位置和保存点之间的交易一样.考虑你的例子:

LSN 1: BEGIN TRAN OUTERTRAN
LSN 2: INSERT INTO ...
LSN 3: BEGIN TRAN INNERTRAN
LSN 4: INSERT INTO ...
LSN 5: ROLLBACK TRAN OUTERTRAN
Run Code Online (Sandbox Code Playgroud)

在日志序列号(LSN)1处,创建OUTERTRAN保存点.第一个INSERT创建LSN 2.然后INNERTRAN创建一个带有LSN 3的保存点.第二个INSERT创建一个新的LSN,4.ROLLBACK OUTERTRAN相当于'ROLLBACK log,直到LSN 1'.您不能"跳过"部分日志,因此必须回滚日志中的每个操作,直到命中LSN 1(创建保存点OUTERTRAN时).

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

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

  • `要回滚到INNERTRAN,您需要使用语法'SAVE TRANSACTION INNERTRAN`来创建一个真正的保存点(而不是命名事务).命名事务主要用于恢复方案(`RESTORE WITH STOPAT OUTERTRAN`) (3认同)