我已经阅读了ROLLBACK TRANSACTIONnesting transactions上的MSDN。虽然我知道ROLLBACK TRANSACTION savepointname的要点,但我不了解ROLLBACK TRANSACTION transactionname

  • 仅当transactionname是最外面的事务
  • 时才有效
  • ROLLBACK总是回滚整个事务“堆栈”,除非是savepointname

  • 基本上,当我阅读文档时,除了保存点之外,ROLLBACK都会回滚所有事务(到@@TRANCOUNT=0)。我可以看到的唯一区别是此代码段:



    从阅读中可以看出,这回滚了一个命名的事务(必须是最外层事务的名称),只有嵌套的事务才被回滚。这将对回滚命名的事务具有一定的意义。所以我建立了一个测试:
    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有什么意义呢?

    最佳答案

    保存点与顾名思义完全相同:日志序列中的“保存点”。对数序列始终是线性的。如果回滚到保存点,则会回滚事务在当前日志位置和保存点之间所做的所有操作。考虑您的示例:

    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创建LSN2。然后INNERTRAN创建一个具有LSN 3的保存点。第二个INSERT创建一个新的LSN4。ROLLBACK OUTERTRAN等效于“ROLLBACK log,直到LSN 1”。您不能“跳过”日志的各个部分,因此必须回滚日志中的每个操作,直到命中LSN 1(创建保存点OUTERTRAN时)为止。

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

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

    10-06 16:06