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

SQL Server 死鎖偵測與處理實戰:TRY-CATCH 捕獲 1205 錯誤

     編輯:關於SqlServer

死鎖本質

兩個或多個 Session 互相持有鎖並請求對方持有的鎖,形成循環等待。SQL Server 死鎖監視器會選擇犧牲者(通常是回滾成本最低者)終止,回傳錯誤 1205。

測試環境建立

-- 表 goods_sort
CREATE TABLE goods_sort (iSortID INT PRIMARY KEY IDENTITY(1001,1), sSortName NVARCHAR(20));
INSERT INTO goods_sort VALUES ('服飾'),('女包'),('鞋子'),('首飾'),('美容');

-- 表 goods
CREATE TABLE goods (iID INT PRIMARY KEY IDENTITY, iGoodsID VARCHAR(20), sGoodsName NVARCHAR(100), iGoodTotal INT DEFAULT 0, iPrice INT DEFAULT 0, iPriceTotal INT, iSortID INT, tAddDate SMALLDATETIME DEFAULT GETDATE());
INSERT INTO goods VALUES ('YR6001','瘦身羽絨服',20,200,4000,1001),('YR6002','加厚羽絨服',20,300,6000,1001),('BB7001','小黃牛皮馬鞍包',30,100,3000,1002),('BB7002','十字繡流蘇包',50,150,7500,1002);

製造死鎖的兩個事務

事務 1:先改 goods_sort 再改 goods

SET NOCOUNT ON; SET XACT_ABORT ON;
BEGIN TRY
    BEGIN TRAN
    UPDATE goods_sort SET sSortName='女鞋' WHERE iSortID=1003;
    WAITFOR DELAY '00:00:05';  -- 增加持鎖時間
    UPDATE goods SET sGoodsName='胖子羽絨服' WHERE iID=2;
    COMMIT TRAN
END TRY
BEGIN CATCH
    IF XACT_STATE()=-1 ROLLBACK TRAN;
    IF ERROR_NUMBER()=1205 PRINT '事務 1 發生死鎖';
END CATCH
SELECT * FROM goods WHERE iID=2;
SELECT * FROM goods_sort WHERE iSortID=1003;

事務 2:先改 goods 再改 goods_sort(相反順序)

SET NOCOUNT ON; SET XACT_ABORT ON;
BEGIN TRY
    BEGIN TRAN
    UPDATE goods SET sGoodsName='瘦子羽絨服' WHERE iID=2;
    WAITFOR DELAY '00:00:05';
    UPDATE goods_sort SET sSortName='男鞋' WHERE iSortID=1003;
    COMMIT TRAN
END TRY
BEGIN CATCH
    IF XACT_STATE()=-1 ROLLBACK TRAN;
    IF ERROR_NUMBER()=1205 PRINT '事務 2 發生死鎖';
END CATCH
SELECT * FROM goods WHERE iID=2;
SELECT * FROM goods_sort WHERE iSortID=1003;

關鍵技巧

  1. TRY-CATCH 確保錯誤後仍能執行後續查詢/記錄。
  2. WAITFOR DELAY 擴大死鎖窗口,穩定複現。
  3. ERROR_NUMBER()=1205 精確識別死鎖,寫入 SQL Server Log 或應用日誌。
  4. XACT_STATE()=-1 判斷不可提交交易,必須回滾。

生產環境死鎖排查流程

  1. 啟用追蹤旗標 1204 / 1222 或擴充事件 xml_deadlock_report 記錄死鎖圖。
  2. 分析死鎖圖:識別參與物件、鎖模式、隔離級別。
  3. 優化手段:
    • 統一存取順序(如永遠先鎖 goods_sort 再鎖 goods)。
    • 縮短交易範圍、降低隔離級別(READ COMMITTED SNAPSHOT)。
    • 加入適當索引減少掃描鎖升級。
    • 使用 ROWLOCK / UPDLOCK 提示精細控制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved