初めてトランザクションを使用するので、ばかげた質問をしている可能性があります。
3 つのテーブルにデータを挿入したい:
Table1(p1,p2,p3)
Table2(q1,q2)
Table3(t3,fk1,fk2)
たとえば、何か問題が発生して にデータを挿入できない場合Table2
、 からのデータはTable1
失われず、変更さTable3
れません (逆も同様です)。
これまでに 2 つのバージョンを試しましたが、どれも満足のいくものではありませんでした。
バージョン 1:
CREATE PROCEDURE InsertInto(@p1,@p2,@p3,@q1,@q2,@t3))
AS BEGIN
BEGIN TRAN
SET XACT_ABORT OFF
SAVE TRANSACTION point1
BEGIN TRY
DECLARE @fk1 INT
INSERT INTO Table1 VALUES (@p1,@p2,@p3)
SELECT @fk1 = Table1.Id FROM Table1 WHERE Table1.p1 = @p1
SAVE TRANSACTION point2
BEGIN TRY
DECLARE @fk2 INT
INSERT INTO Table2 VALUES (@q1,@q2)
SELECT @fk2 = Table2.Id FROM Table2 WHERE Table2.q1 = @q1
SAVE TRANSACTION point3
BEGIN TRY
INSERT INTO Table3 VALUES (@t3, @fk1, @fk2)
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION point3
COMMIT TRAN
END CATCH
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION point2
COMMIT TRAN
END CATCH
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION point1
COMMIT TRAN
END CATCH
END
しかし、データを に挿入できない場合はTable1
、可能なデータTable2
が失われ、何も失いたくありません。というわけで、分けてみました。
バージョン 2:
CREATE PROCEDURE InsertInto(@p1,@p2,@p3,@q1,@q2,@t3)
AS
BEGIN
BEGIN TRAN
SET XACT_ABORT OFF
SAVE TRANSACTION point1
BEGIN TRY
DECLARE @fk1 INT
INSERT INTO Table1 VALUES (@p1,@p2,@p3)
SELECT @fk1 = Table1.Id FROM Table1 WHERE Table1.p1 = @p1
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION point1
COMMIT TRAN
END CATCH
SAVE TRANSACTION point2
BEGIN TRY
DECLARE @fk2 INT
INSERT INTO Table2 VALUES (@q1,@q2)
SELECT @fk2 = Table2.Id FROM Table2 WHERE Table2.q1 = @q1
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION point2
COMMIT TRAN
END CATCH
SAVE TRANSACTION point3
BEGIN TRY
INSERT INTO Table3 VALUES (@t3,@fk1,@fk2)
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION point3
COMMIT TRAN
END CATCH
END
しかし、Table2 への挿入が失敗した場合は、次のようになります。
(1 行が影響を受けます)
(影響を受ける行は 0 行)
メッセージ 628、レベル 16、状態 0、手順 InsertInto、行 26 (2 番目の BEGIN CATCH)
アクティブなトランザクションがない場合、SAVE TRANSACTION を発行できません。
どうすればこれを正しく行うことができますか?