2012-04-24 76 views
10

如果存在任何問題,測試插入/更新失敗並回滾此事務的正確方法是什麼?我不認爲我所擁有的將會起作用,因爲我的插入/更新是3個獨立的語句,而@@ ROWCOUNT只會反映最後執行的語句。圍繞多次插入或更新使用事務的正確方法

BEGIN TRANSACTION Script; 
GO 

INSERT INTO TableA (id) VALUES (1) 
INSERT INTO TableB (id) VALUES (1) 
UPDATE TableC SET id=1 WHERE id=2 
GO 

IF (@@ROWCOUNT=3 AND @@ERROR=0) 
    BEGIN 
    COMMIT 
    END 
ELSE 
    BEGIN 
    PRINT 'Error: Rolling back transaction' 
    ROLLBACK TRANSACTION Script 
    END 
GO 

回答

33

如果在啓動事務之前將SET XACT_ABORT設置爲ON,in case of an error, rollback will be issued automatically

SET XACT_ABORT ON 

begin transaction 

INSERT INTO TableA (id) VALUES (1) 
INSERT INTO TableB (id) VALUES (1) 
UPDATE TableC SET id=1 WHERE id=2 

commit transaction 

如果你想自己回滾,use try .. catch block

begin transaction 

begin try 

    INSERT INTO TableA (id) VALUES (1) 
    INSERT INTO TableB (id) VALUES (1) 
    UPDATE TableC SET id=1 WHERE id=2 

    commit transaction 

end try 

begin catch 
    raiserror('Message here', 16, 1) 
    rollback transaction 
end catch 
+0

這限制了我從打印失敗的消息,對不對? – 2012-04-24 17:26:08

+0

@JoePhilllips請檢查我的更新答案。 – 2012-04-24 17:30:30

+1

事務回滾時,SET XACT_ABORT ON屬性是否會引發錯誤消息? – Raza 2014-06-11 09:16:11

0

失敗的插入會拋出。使用@@ ROWCOUNT可以檢測到「失敗」更新。

2

我不知道你是什麼版本,但由於SQL 2005出現了try/catch語句:

begin transaction 
begin try 
    INSERT INTO TableA (id) VALUES (1) 
    INSERT INTO TableB (id) VALUES (1) 
    UPDATE TableC SET id=1 WHERE id=2 
end try 
begin catch 
    SELECT 
     ERROR_NUMBER() AS ErrorNumber, 
     ERROR_SEVERITY() AS ErrorSeverity, 
     ERROR_STATE() AS ErrorState, 
     ERROR_PROCEDURE() AS ErrorProcedure, 
     ERROR_LINE() AS ErrorLine, 
     ERROR_MESSAGE() AS ErrorMessage; 
    while(@@trancount > 0) 
    begin 
     rollback transaction 
    end 
end catch 
if (@@trancount <> 0) 
begin 
    commit transaction; 
end