0
我第一次使用事務,所以我可能會問一個愚蠢的問題。什麼是使用多個保存點的正確方法
我想在3個表中插入數據:
Table1(p1,p2,p3)
Table2(q1,q2)
Table3(t3,fk1,fk2)
例如,如果出現錯誤和數據不能插入Table2
,從Table1
數據不會丟失,Table3
保持不變(反之亦然) 。
到目前爲止我已經嘗試了兩個版本,但沒有一個令人滿意。
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
可能的數據丟失,我不想失去任何東西:
第1版。所以,我試圖分裂它。
版本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
但如果插入到表2失敗,我得到這個:
(1行(S)的影響)
(0行(S)的影響)
消息628,級別16,狀態0,過程插入進來,行26(第二個開始捕獲)
當沒有活動交易時,不能發出存儲交易上。
我該如何做到這一點?
看來你不應該在這裏使用保存點,而只是在每一步之後提交,然後開始一個新的事務。你能澄清你爲什麼使用保存點嗎?也許你的代碼的某些用法根本不清楚。 – hvd
我想了解如何使用保存點,以便在事務處理期間不丟失數據。 – user1012732