“ROLLBACK TRANSACTION named_transaction”有什么意义?

时间:2009-11-28 20:59:33

标签: tsql sql-server-2008 transactions rollback

我在ROLLBACK TRANSACTIONnesting transactions上阅读了MSDN。虽然我看到了ROLLBACK TRANSACTION savepointname的观点,但我不明白ROLLBACK TRANSACTION transactionname

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

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

      

    如果使用名称的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 named_transaction是什么意思?

1 个答案:

答案 0 :(得分: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,直到LSN 1'。您不能“跳过”部分日志,因此您必须回滚日志中的每个操作,直到LSN 1(创建保存点OUTERTRAN时)被命中。

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

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