6

ROLLBACK TRANSACTIONネストされたトランザクションに関する MSDN を読みました。のポイントを見ているうちにROLLBACK TRANSACTION savepointname、わからないROLLBACK TRANSACTION transactionname

  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行」のものは削除されました)

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

4

1 に答える 1

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 でセーブ ポイントを作成します。2 番目の INSERT は、新しい LSN 4 を作成します。ROLLBACK OUTERTRAN は、「LSN 1 までの ROLLBACK ログ」と同等です。ログの一部を「スキップ」することはできないため、LSN 1 (セーブ ポイント OUTERTRAN が作成されたとき) に到達するまで、ログ内のすべての操作をロールバックする必要があります。

一方、最後の操作で ROLLBACK INNERTRAN を発行すると、エンジンは LSN 3 (「INNERTRAN」セーブポイントがログに挿入された場所) までロールバックし、LSN 1 と LSN 2 (つまり、最初の INSERT) を保存します。 )。

セーブ ポイントの実用的な例については、「例外処理とネストされたトランザクション」を参照してください。

于 2009-11-28T21:14:42.970 に答える