Sql-Server

XACT_ABORT ON 在 SQL Server 2012 上無法按預期工作?

  • July 15, 2021

看起來 XACT_ABORT ON 沒有按預期工作。這是一個表格和一個插入其中的過程:

CREATE TABLE rain
   (
     rain_time DATETIME ,
     location VARCHAR(100)
   );
GO

CREATE PROCEDURE insert_rain
   @rain_time DATETIME ,
   @location VARCHAR(100)
AS
   BEGIN;
       SET XACT_ABORT ON;
       BEGIN TRANSACTION;
       PRINT 'before insert';
       INSERT  INTO rain
               ( rain_time, location )
       VALUES  ( @rain_time, @location );
       PRINT 'after insert';
       COMMIT;
   END;
GO

我創建了一個觸發器來模擬執行時錯誤:

CREATE TRIGGER rain_no_insert
ON rain
FOR INSERT 
AS
RAISERROR('Cannot insert', 16, 1);
GO

當我呼叫插入過程時,我確實得到了錯誤,但執行並沒有停止,因為最後一個 PRINT 列印了它的“插入後”消息:

EXEC insert_rain
   @rain_time = '2015-03-30 12:34:56',
   @location = 'Wautoma, WI';

before insert
Msg 50000, Level 16, State 1, Procedure rain_no_insert, Line 5
Cannot insert

(1 row(s) affected)
after insert

事務也送出:

SELECT * FROM dbo.rain;

rain_time               location
----------------------- ---------------------------------
2015-03-30 12:34:56.000 Wautoma, WI

為什麼我的 XACT_ABORT 沒有中止?

檢查 Microsoft 文件,特別是第一行:

THROW 語句支持 SET XACT_ABORT。RAISERROR 沒有。新應用程序應使用 THROW 而不是 RAISERROR。

我相信那是你的問題,就在那裡。

https://msdn.microsoft.com/en-us/library/ms188792.aspx

您還可以在插入語句周圍放置一個 try-catch 並很好地處理錯誤。

create PROCEDURE insert_rain
  @rain_time DATETIME ,
  @location VARCHAR(100)
AS
BEGIN;
  SET XACT_ABORT ON;
  BEGIN TRANSACTION;
  PRINT 'before insert';

  BEGIN TRY
     insert INTO rain
        ( rain_time, location )
        values  ( @rain_time, @location );
     PRINT 'after insert';

     COMMIT;
  end try
  begin catch;
     if @@trancount > 0
        rollback;
     throw;
  end catch;
END;
go

引用自:https://dba.stackexchange.com/questions/96617