2009-11-28 69 views
6

我已閱讀了關於ROLLBACK TRANSACTIONnesting transactions的MSDN。雖然我看到ROLLBACK TRANSACTION savepointname的觀點,但我不明白ROLLBACK TRANSACTION transactionname「ROLLBACK TRANSACTION named_transaction」的含義是什麼?

  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行(S)」的東西去掉)

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 TRANSACTION named_transaction有什麼意義?

回答

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日誌,直到LSN 1'。您不能'跳過'部分日誌,因此您必須回滾日誌中的每個操作,直到LSN 1(創建保存點OUTERTRAN時)爲止。另一方面,如果在上一次操作中發出ROLLBACK INNERTRAN,則引擎將回退,直到LSN 3('INNERTRAN'保存點插入日誌中),從而保留LSN 1和LSN 2(即。第一個INSERT)。

有關保存點的實際示例,請參閱Exception handling and nested transactions

+0

Remus,謝謝。我正在查看你的鏈接... – 2009-11-28 21:19:40

+0

好吧,我明白你已經做了什麼。但是,我仍然對我的原始觀點感到好奇。我得到了保存點和它們的價值,但我仍然對回滾事務(不保存點)名稱感到困惑。一個重要的說明,顯然你不能ROLLBACK一個內部交易。例如ROLLBACK TRAN INNERTRAN導致錯誤「無法回滾INNERTRAN,沒有找到該名稱的事務或保存點」。這一點(關於回滾命名嵌套事務被禁止)在我在OP中提到的文檔鏈接中。 – 2009-11-28 21:28:55

+3

'要回滾到INNERTRAN,您需要使用語法'SAVE TRANSACTION INNERTRAN'來創建一個真正的保存點(而不是命名事務)。命名事務主要用於恢復場景('RESTORE WITH STOPAT OUTERTRAN') – 2009-11-28 21:32:18