在多个插入或更新周围使用事务的正确方法

时间:2012-04-24 17:11:16

标签: sql-server transactions

测试插入/更新失败并回滚此事务的正确方法是什么?我不认为我的工作会有效,因为我的插入/更新是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

3 个答案:

答案 0 :(得分:38)

如果在开始交易之前将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

答案 1 :(得分:4)

我不知道你在使用什么版本,但自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

答案 2 :(得分:0)

失败的插入将抛出。可以使用@@ ROWCOUNT检测“失败”更新。