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

SQL Server 鎖機制深度解析:粒度、模式、升級、死鎖偵測與避免策略

     編輯:關於SqlServer

鎖的必要性:四大並發異常

  1. 遺失更新:兩事務讀同一列、各自更新,後寫入覆蓋先寫入。
  2. 髒讀:事務讀取另一事務未提交的修改,後者回滾導致資料不存在。
  3. 不可重複讀:同一事務兩次讀同一列,中間被他事務修改,結果不一致。
  4. 幻讀:事務讀取範圍,他事務插入新列符合範圍,重讀時出現「幻影」列。

多粒度鎖定架構

SQL Server 支援層級:資料列 → 頁 (8KB) → 區 (8頁) → 資料表 → 資料庫。

  • 列鎖:粒度最細,並發最高,但鎖數量多、記憶體開銷大。
  • 頁鎖:SQL 7.0 前預設,鎖定整頁,即使只改一列也阻塞該頁其他列。
  • 表鎖:系統資源最少,但並發最低,大量資料操作時自動升級使用。
  • 區鎖:僅用於配置空間(建庫、建表),防止同區重複配置。
  • 資料庫鎖:僅用於資料庫還原,設定單一使用者模式。

鎖升級

當單一事務持有大量細粒度鎖(列/頁)超過閾值,系統自動升級為表鎖以降低管理開銷。閾值由動態演算法決定,無需人工設定。

六大鎖模式

  1. 共享鎖 (S):唯讀操作(SELECT),多事務可同時持有,讀完即釋放(除非 HOLDLOCK)。
  2. 更新鎖 (U):修改初期防死鎖,讀取時取 U 鎖,修改時轉 X 鎖,避免 S→X 升級死鎖。
  3. 排他鎖 (X):資料修改(INSERT/UPDATE/DELETE),獨佔資源,阻塞其他讀寫。
  4. 結構鎖 (Sch-M/Sch-S):DDL 操作取 Sch-M;編譯查詢取 Sch-S,不阻塞任何鎖含 X,但阻塞 DDL。
  5. 意圖鎖 (IS/IX/SIX):表示在較低層級將取得 S/X 鎖,協調多粒度鎖相容性。
  6. 大量更新鎖 (BU):BULK INSERT 配合 TABLOCK 時使用,允許並發大量載入,阻塞非大量操作。

表提示控制鎖行為

提示效果
HOLDLOCK持有 S 鎖至交易結束
NOLOCK / READUNCOMMITTED不加鎖,可能讀髒資料,僅限 SELECT
PAGLOCK強制頁鎖
READCOMMITTED提交讀隔離級別語意
READPAST跳過已鎖列,僅限 READ COMMITTED
REPEATABLEREAD可重複讀隔離級別
ROWLOCK強制列鎖
SERIALIZABLE可序列化隔離級別,等同 HOLDLOCK
TABLOCK表級 S 鎖,陳述式結束釋放;配合 HOLDLOCK 持有至交易結束
TABLOCKX表級 X 鎖,阻塞所有讀寫
UPDLOCK讀取時取 U 鎖,持有至陳述式/交易結束

死鎖偵測與犧牲者選擇

  • 系統定期掃描等待圖,偵測到循環等待(鎖請求環)即判定死鎖。
  • 自動選擇「回滾成本最低」的事務作為犧牲者,回滾並返回 1205 錯誤。
  • 可用 SET DEADLOCK_PRIORITY LOW 降低會話優先權,增加被選為犧牲者機率。

應用層避免死鎖六大原則

  1. 統一資料表存取順序(所有程式依相同順序鎖表)。
  2. 交易簡短、單一批次完成,避免使用者介入等待。
  3. 時域離散:排程後台作業錯峰,避開前台尖峰,工作流限制同類任務併發數。
  4. 空域離散:大表拆分(水平/垂直/按用戶群),減少熱點爭用。
  5. 使用最低足夠隔離等級(預設 READ COMMITTED),避免過度 SERIALIZABLE。
  6. 綁定連接 (sp_getbindtoken/sp_bindsession) 共享鎖與交易,消除同邏輯單元內鎖衝突。

結語

理解鎖粒度、模式、升級與死鎖機制,配合應用層設計原則,是 DBA 與開發人員構建高並發、高一致性系統的核心功力。

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