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

SQL Server 2005 死結解決方案:TRY...CATCH 重試機制實作

     編輯:關於SqlServer

死結重現與舊版困境

兩個連線 5 秒內同時執行特定插入/查詢序列會產生死結。SQL Server 犧牲一個連線拋出異常回滾。SQL Server 2000 中異常發生後 T-SQL 停止執行,PRINT 等後續陳述式不會執行,難以在 T-SQL 內處理死結。

SQL Server 2005 突破:TRY...CATCH 異常捕獲

支援 T-SQL 結構化錯誤處理,提供死結重試路徑。

基礎重試邏輯

SET XACT_ABORT ON;
DECLARE @r INT = 1;
WHILE @r <= 3
BEGIN
    BEGIN TRAN;
    BEGIN TRY
        INSERT INTO Orders(CustomerId) VALUES('ALFKI');
        WAITFOR DELAY '00:00:05';
        SELECT * FROM Orders WHERE CustomerId = 'ALFKI';
        COMMIT;
        BREAK;
    END TRY
    BEGIN CATCH
        ROLLBACK;
        WAITFOR DELAY '00:00:03'; -- 衝突後等待,必要
        SET @r = @r + 1;
        CONTINUE;
    END CATCH;
END;

關鍵點:ROLLBACK 後必須 WAITFOR DELAY 讓衝突釋放;@retry 可依需求調整。

進階:錯誤重新拋出避免吞沒

重試超過上限後異常被吞沒。SQL Server 2005 提供 RAISERROR 但無法直接拋出原始異常,需重新定義錯誤資訊:

IF ERROR_NUMBER() <> 0
BEGIN
    DECLARE @ErrorMessage NVARCHAR(4000), @ErrorSeverity INT, @ErrorState INT;
    SELECT
        @ErrorMessage = ERROR_MESSAGE(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE();
    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
END;

期待未來版本提供無參數 RAISERROR 直接重拋原始異常。

架構優勢

將死結處理封裝於 T-SQL 內,明確職責分離,上層資料存取程式碼無需關心死結邏輯,提升系統清晰度。

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