首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 2000 事務回滾陷阱:SET XACT_ABORT ON 的必要性

     編輯:關於SqlServer

問題現象

在 SQL Server 2000 中,若存儲過程內發生嚴重錯誤(如除零、轉換失敗),批次會直接終止,後續的 IF @@ERROR != 0 判斷根本不會執行,導致事務無法回滾,數據處於不一致狀態。

解決方案:開啟 XACT_ABORT

CREATE PROCEDURE test_tran
AS
    SET XACT_ABORT ON;  -- 關鍵:遇嚴重錯誤自動回滾整個事務並中止批次
    BEGIN TRANSACTION RemoteUpdate;
    INSERT psn_degree VALUES (22, 'test');
    SELECT 1/0;         -- 故意製造除零錯誤
    IF @@ERROR != 0
    BEGIN
        ROLLBACK TRANSACTION RemoteUpdate;
        RAISERROR('出錯!網絡速度慢或斷線!', 16, 16) WITH SETERROR;
        RETURN;         -- 必須 RETURN,否則會繼續向下執行 COMMIT
    END
    ELSE
    BEGIN
        COMMIT TRANSACTION RemoteUpdate;
    END
GO

簡化寫法(推薦)

CREATE PROCEDURE test_tran
AS
    SET XACT_ABORT ON;
    BEGIN TRANSACTION RemoteUpdate;
    INSERT psn_degree VALUES (22, 'test');
    SELECT 1/0;
    IF @@ERROR != 0
    BEGIN
        ROLLBACK TRANSACTION RemoteUpdate;
        RAISERROR('出錯!', 16, 1) WITH SETERROR;
        RETURN;
    END
    COMMIT TRANSACTION RemoteUpdate;  -- 正常路徑隱式提交
GO

核心要點

  1. SET XACT_ABORT ON 是 2000/2005 時代事務安全的基石,現代版本(2005+)建議改用 TRY...CATCH。
  2. @@ERROR 僅捕獲非致命錯誤;嚴重錯誤會跳過後續語句,必須靠 XACT_ABORT 保證回滾。
  3. RETURN 後不可再有代碼,否則邏輯錯亂。
  4. RAISERROR ... WITH SETERROR 將 @@ERROR 置為非零,便於客戶端感知。

現代最佳實踐(SQL 2005+)

CREATE PROCEDURE ModernTran
AS
BEGIN
    SET XACT_ABORT ON;  -- 依然建議保留
    BEGIN TRY
        BEGIN TRANSACTION;
        INSERT psn_degree VALUES (22, 'test');
        SELECT 1/0;
        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
        THROW;  -- 重新拋出原始錯誤,保留堆疊
    END CATCH
END

結語

老版本靠 SET XACT_ABORT ON 兜底,新版本用 TRY...CATCH 更優雅。無論哪個時代,事務要么全成要么全敗 是不變的鐵律。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved