交易是資料庫一致性的基石,鎖是並發控制的手段。本文系統梳理 SQL Server 交易控制語句、ACID 特性、可鎖定資源層級、六大鎖模式、相容性矩陣、死鎖錯誤碼與排查思路。
一、交易控制語句
| 語句 | 作用 |
BEGIN TRAN[SACTION] | 標記交易起始點 |
COMMIT TRAN[SACTION] | 提交,變更永久生效 |
ROLLBACK TRAN[SACTION] | 回滾,撤銷所有變更 |
SAVE TRAN[SACTION] savepoint | 建立存檔點,支援部分回滾 |
二、交易日誌運作
- 寫前日誌:資料頁修改前,先將邏輯操作寫入記憶體日誌緩衝區
COMMIT 時強制將日誌刷入磁碟(WAL),保證持久性
- 檢查點 定期將髒頁刷盤,縮短復原時間
三、可鎖定資源層級(由粗到細)
- Database:DDL 變更結構時
- Table:整表鎖定,含資料列與所有索引鍵
- Extent (區段):8 頁 = 64KB
- Page (頁):8KB,資料或索引頁
- Key (索引鍵):索引中的特定鍵值範圍
- Row / RID (列/列標識符):最細粒度,實際鎖定 RID
SQL Server 採用鎖升級:細粒度鎖數量超過閾值(約 5000)自動升級為表鎖,可用 ALTER TABLE ... SET (LOCK_ESCALATION = AUTO/DISABLE) 控制。
四、六大鎖模式
| 模式 | 縮寫 | 用途 | 特徵 |
| 共享鎖 | S | SELECT、掃描 | 可共存,讀不阻讀 |
| 排他鎖 | X | INSERT/UPDATE/DELETE | 獨佔,阻擋所有其他鎖 |
| 更新鎖 | U | 尋找待更新資料 | S+X 混合:先兼容 S,確認更新再轉 X,預防死鎖 |
| 意向鎖 | IS/IX/IU | 層級協調 | 標示下層有鎖,如 IX 表示「下層有 X」 |
| 結構鎖 | Sch-M/Sch-S | DDL vs 查詢 | Sch-M 修改結構(獨佔),Sch-S 穩定結構(共享) |
| 大量更新鎖 | BU | BULK INSERT | 允許並行大量載入 |
五、鎖相容性矩陣(核心)
口訣:S 兼容 S/IS/IX;X 只兼容無;U 兼容 S/IS,不兼容 U/X/IX。意向鎖只與結構鎖衝突,不與資料鎖直接衝突。
六、死鎖與排查
- 錯誤碼:1205(Victim 選中者回滾,其他繼續)
- 捕捉:
DBCC TRACEON(1222, -1)、Extended Events (xml_deadlock_report)、sys.dm_tran_locks 即時查看
- 常見成因:
- 多交易以不同順序存取相同資源(表 A → B vs B → A)
- 索引缺失導致掃描鎖升級為表鎖
- 長交易持有鎖過久
- 預防:
- 固定存取順序(如按 PK 排序)
- 縮短交易範圍、避免交易中呼叫外部 API
- 加強索引減少掃描範圍
- 適當使用
ROWLOCK / UPDLOCK / HOLDLOCK Hint
- 啟用
READ_COMMITTED_SNAPSHOT(RCSI)讓讀不阻寫
七、ACID 四大特性
| 特性 | 英文 | SQL Server 實現 |
| 原子性 | Atomicity | 交易全做或全不做,日誌保證 |
| 一致性 | Consistency | 約束、觸發器、外鍵、檢查點 |
| 隔離性 | Isolation | 鎖 + 版本存儲(RCSI/SI) |
| 持久性 | Durability | WAL、強制寫入日誌檔 |
八、隔離等級與現象對照
| 隔離等級 | 髒讀 | 不可重複讀 | 幻讀 | 實現機制 |
| READ UNCOMMITTED | Y | Y | Y | 無 S 鎖 |
| READ COMMITTED | N | Y | Y | S 鎖讀完即釋放 |
| REPEATABLE READ | N | N | Y | S 鎖持有至交易結束 |
| SNAPSHOT | N | N | N | 版本存儲(行版本) |
| SERIALIZABLE | N | N | N | 範圍鎖 |
預設為 READ COMMITTED。高並發建議開啟 READ_COMMITTED_SNAPSHOT ON,以行版本替代共享鎖,大幅降低阻塞。
- 上一篇文章: 50 道 SQL 進階查詢實戰:從學生成績到複雜排名、橫縱轉換、Top-N 全覆蓋
- 下一篇文章: SQL Server 預存程序實戰精要:ALTER vs CREATE、輸出參數陷阱、優缺點權衡與動態 SQL
Copyright ©
程式碼之家 All Rights Reserved