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

SQL Server 2008 鎖機制深度解析:模式、資源、升級與表級控制

     編輯:SQL Server 2005

一、鎖的基本概念

鎖是關聯式資料庫為保證資料完整性、防止並發問題(髒讀、不可重複讀、幻讀、更新丟失)而實施的同步機制。SQL Server 動態管理鎖,但理解其運作有助於調優與故障排查。

二、主要鎖模式

模式縮寫用途
共享鎖S唯讀操作(SELECT),相容 S/U,不相容 X。
更新鎖U可更新資源的預備鎖,防止死鎖,相容 S,不相容 U/X。
排他鎖X資料修改(INSERT/UPDATE/DELETE),不相容任何其他鎖。
意向鎖IS/IX/SIX建立鎖層級,表示下層將加 S/X 鎖。
結構描述鎖Sch-M/Sch-SDDL 操作(Sch-M)與查詢編譯(Sch-S)互斥。
大量更新鎖BUBULK INSERT 配合 TABLOCK 時使用。
鍵範圍鎖RangeS/RangeX可序列化隔離級保護範圍查詢,防止幻讀。

三、可鎖定資源與粒度

資源說明
KEY索引鍵值(範圍鎖用)
PAGE8KB 頁(資料/索引頁)
EXTENT8 頁組成的區塊
HoBTHeap 或 B-Tree(無叢集索引表的資料/索引)
TABLE整張表(含所有索引)
FILE資料庫檔案
RIDHeap 中單一資料列識別碼
DATABASE整個資料庫
APPLICATION應用自定義資源(sp_getapplock)
METADATA系統目錄中繼資料
ALLOCATION_UNIT配置單元

粒度權衡:細粒度(ROW/KEY)並發高但記憶體消耗大;粗粒度(TABLE)記憶體少但並發低。SQL Server 會自動升級鎖。

四、鎖相容性矩陣(核心規則)

  • X 與任何鎖不相容。
  • U 僅相容 S。
  • S 相容 S、U。
  • 意向鎖(IS/IX/SIX)間相容規則較複雜,核心是 IX 與 IX 相容,IX 與 S 不相容等。

五、鎖升級

觸發條件:

  1. 單一 T-SQL 陳述式在單一表/索引上取得 > 5,000 個鎖。
  2. 實例總鎖數超過記憶體閾值(約 40% 非 AWE 記憶體)。

升級將細粒度鎖(ROW/PAGE)轉為粗粒度(TABLE),釋放記憶體但降低並發。SQL Server 2008 引入表選項控制升級行為:

六、SQL Server 2008 新增:表級鎖升級控制 (ALTER TABLE ... SET (LOCK_ESCALATION = ...))

選項行為
TABLE (預設)表級升級,無論是否分區。
AUTO分區表→分區級升級(HoBT);非分區表→表級升級。
DISABLE停用表級升級。例外:TABLOCK 提示或可序列化隔離級下的 Heap 仍可能產生表鎖。

範例

-- 設為分區級升級
ALTER TABLE Person.Address SET (LOCK_ESCALATION = AUTO);
SELECT lock_escalation, lock_escalation_desc FROM sys.tables WHERE name = 'Address';
-- 結果: 2, AUTO

-- 停用升級
ALTER TABLE Person.Address SET (LOCK_ESCALATION = DISABLE);
SELECT lock_escalation, lock_escalation_desc FROM sys.tables WHERE name = 'Address';
-- 結果: 1, DISABLE

七、實戰:用 sys.dm_tran_locks 監視鎖活動

-- 會話 1:加排他表鎖
BEGIN TRAN
SELECT * FROM Production.ProductDocument WITH (TABLOCKX);

-- 會話 2:查詢當前鎖
SELECT request_session_id AS sessionid,
       resource_type AS type,
       resource_database_id AS dbid,
       OBJECT_NAME(resource_associated_entity_id, resource_database_id) AS objectname,
       request_mode AS rmode,
       request_status AS rstatus
FROM sys.dm_tran_locks
WHERE resource_type IN ('DATABASE', 'OBJECT');

結果會顯示 ProductDocument 上的 X 鎖(GRANT)。

資源關聯實體 ID 解析規則

  • resource_type = OBJECT → resource_associated_entity_id 為 object_id,可用 sys.objects 查名稱。
  • resource_type = ALLOCATION_UNIT → 該 ID 為 allocation_unit_id,需 join sys.allocation_units → sys.partitions 取 object_id。
  • resource_type = KEY/PAGE/RID/HOBT → 該 ID 為 hobt_id,直接查 sys.partitions 取 object_id。
  • resource_type = DATABASE/EXTENT/APPLICATION/METADATA → 該 ID 為 0。

八、調優建議

  • 適當索引減少掃描範圍,降低鎖數量與升級機率。
  • 避免長事務、使用者互動在事務中、大批次更新拆分。
  • 分區大表可設 LOCK_ESCALATION = AUTO 將升級限制在分區層級。
  • 高並發唯讀場景考慮 READ COMMITTED SNAPSHOT (RCSI) 或快照隔離,以行版本替代共享鎖。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved