いいえSAVE TRANSACTION
。私はこれを使用するためのケースを見つけたことがありません。私は一部の人々がそれを好むことを知っていますが、私が働いたことのある場所でこれまでに行ったことすべてにおいて、ネストされたレベルのいずれかでエラーが発生するという概念は、すでに行われた作業が無効であることを意味しました。を使用SAVE TRANSACTION
すると、このストアドプロシージャが呼び出される直前の状態に戻るだけで、既存のプロセスは他の方法で有効なままになります。
の詳細が必要な場合はSAVE TRANSACTION
、この回答の情報をご覧ください。
1つのストアドプロシージャから3つのストアドプロシージャが開始されたときにロールバックする方法
もう1つの問題SAVE TRANSACTION
は、MSDNページのSAVE TRANSACTION(強調が追加されている)に記載されているように、その動作のニュアンスです。
トランザクションでは重複するセーブポイント名を使用できますが、セーブポイント名を指定するROLLBACK TRANSACTIONステートメントは、その名前を使用する最新の SAVE TRANSACTIONにのみトランザクションをロールバックします。
つまり、各ストアドプロシージャの各セーブポイントに、すべてのストアドプロシージャのすべてのセーブポイントで一意の名前を付けるように注意する必要があります。次の例は、この点を示しています。
この最初の例は、セーブポイント名を再利用するとどうなるかを示しています。最下位レベルのセーブポイントのみがロールバックされます。
IF (OBJECT_ID(N'tempdb..#SaveTranTestA') IS NOT NULL)
BEGIN
DROP TABLE #SaveTranTestA;
END;
CREATE TABLE #SaveTranTestA (SomeVal INT NOT NULL);
BEGIN TRAN; -- start level 1
SAVE TRANSACTION MySavePoint;
SELECT @@TRANCOUNT AS [TranCount]; -- 1
INSERT INTO #SaveTranTestA (SomeVal) VALUES (100);
BEGIN TRAN; -- start level 2
SAVE TRANSACTION MySavePoint;
SELECT @@TRANCOUNT AS [TranCount]; -- 2
INSERT INTO #SaveTranTestA (SomeVal) VALUES (200);
COMMIT; -- exit level 2
SELECT @@TRANCOUNT AS [TranCount]; -- 1
SELECT * FROM #SaveTranTestA;
-- 100
-- 200
ROLLBACK TRANSACTION MySavePoint; -- error occurred; undo actions up to this point
SELECT @@TRANCOUNT AS [TranCount]; -- 1
SELECT * FROM #SaveTranTestA;
-- 100
COMMIT; -- exit level 1
SELECT @@TRANCOUNT AS [TranCount]; -- 0
SELECT * FROM #SaveTranTestA;
-- 100
この2番目の例は、一意のセーブポイント名を使用するとどうなるかを示しています。目的のレベルのセーブポイントがロールバックされます。
IF (OBJECT_ID(N'tempdb..#SaveTranTestB') IS NOT NULL)
BEGIN
DROP TABLE #SaveTranTestB;
END;
CREATE TABLE #SaveTranTestB (SomeVal INT NOT NULL);
BEGIN TRAN; -- start level 1
SAVE TRANSACTION MySavePointUno;
SELECT @@TRANCOUNT AS [TranCount]; -- 1
INSERT INTO #SaveTranTestB (SomeVal) VALUES (100);
BEGIN TRAN; -- start level 2
SAVE TRANSACTION MySavePointDos;
SELECT @@TRANCOUNT AS [TranCount]; -- 2
INSERT INTO #SaveTranTestB (SomeVal) VALUES (200);
COMMIT; -- exit level 2
SELECT @@TRANCOUNT AS [TranCount]; -- 1
SELECT * FROM #SaveTranTestB;
-- 100
-- 200
ROLLBACK TRANSACTION MySavePointUno; --error occurred; undo actions up to this point
SELECT @@TRANCOUNT AS [TranCount]; -- 1
SELECT * FROM #SaveTranTestB;
-- <no rows>
COMMIT; -- exit level 1
SELECT @@TRANCOUNT AS [TranCount]; -- 0
SELECT * FROM #SaveTranTestB;
-- <no rows>