【问题标题】:What is the point of "ROLLBACK TRANSACTION named_transaction"?“ROLLBACK TRANSACTION named_transaction”有什么意义?
【发布时间】:2010-12-21 06:57:10
【问题描述】:

我已经阅读了 ROLLBACK TRANSACTIONnesting transactions 上的 MSDN。虽然我看到ROLLBACK TRANSACTION savepointname 的意思,但我不明白ROLLBACK TRANSACTION transactionname

  1. 仅当transactionname 是最外层事务时才有效
  2. ROLLBACK 总是回滚整个事务“堆栈”,savepointname 的情况除外

基本上,当我阅读文档时,除了保存点之外,ROLLBACK 会回滚所有事务(到@@TRANCOUNT=0)。我能看到的唯一区别是这个 sn-p:

如果一个 ROLLBACK TRANSACTION transaction_name 语句使用名称 外部事务在一组嵌套的任何级别执行 事务,所有嵌套事务都会回滚。 如果 ROLLBACK WORK 或 ROLLBACK TRANSACTION 语句没有 transaction_name 参数在一组嵌套的任何级别执行 事务,它回滚所有嵌套事务,包括 最外层的事务。

从阅读中,这向我表明回滚命名事务(必须是最外层事务的名称),只会回滚嵌套事务。这将为回滚命名事务提供一些意义。所以我设置了一个测试:

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 <b>named_transaction</b>的意义何在?

【问题讨论】:

    标签: tsql sql-server-2008 transactions rollback


    【解决方案1】:

    保存点正如名字所暗示的那样:日志序列中的“保存点”。对数序列始终是线性的。如果您回滚到一个保存点,您将回滚您的事务在当前日志位置和保存点之间所做的一切。考虑你的例子:

    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(即。第一个插入)。

    有关保存点的实际示例,请参阅Exception handling and nested transactions

    【讨论】:

    • 好的,我知道你做了什么。但是,我仍然对我原来的观点感到好奇。我得到了保存点及其价值,但我仍然对回滚事务(不是保存点)名称感到困惑。一个重要的注意事项,显然你不能回滚内部事务。例如,ROLLBACK TRAN INNERTRAN 会导致错误“无法回滚 INNERTRAN。未找到该名称的事务或保存点。”。这一点(关于不允许回滚命名嵌套事务)在我在 OP 中提到的文档链接中。
    • To rollback to INNERTRAN you need to use the syntax 'SAVE TRANSACTION INNERTRAN 创建一个真正的保存点(与命名事务相反)。命名事务主要用于恢复场景 (RESTORE WITH STOPAT OUTERTRAN)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 2017-06-30
    • 2016-01-05
    • 2021-06-03
    相关资源
    最近更新 更多