SQL Server 完整锁类型详解
你想了解 SQL Server 中的所有锁类型,SQL Server 的锁按锁定资源粒度 和锁的功能类型可分为两大核心分类,同时有明确的兼容性规则,下面为你逐一拆解所有关键锁类型:
一、 按锁的功能类型分类(核心业务相关锁)
这是日常开发、排查锁阻塞时最常接触的锁类型,按"共享/排他/特殊功能"划分:
1. 共享类锁(允许多会话同时持有,不相互阻塞)
| 锁类型标识 | 锁名称 | 核心用途 | 关键特性 |
|---|---|---|---|
| S | 共享锁(Shared Lock) | 保护数据读取操作(如 SELECT),防止读取期间数据被修改 |
1. 多个会话可同时持有同一资源的 S 锁 2. 与 X 锁(排他锁)、U 锁(更新锁)互斥 3. 阻塞写操作(INSERT/UPDATE/DELETE),不阻塞读操作 4. 默认读完即释放(事务内持有至事务结束) |
| Sch-S | 架构稳定性锁(Schema Stability Lock) | 保护对象架构(表、视图等)不被修改,确保访问对象期间架构稳定 | 1. 所有访问对象的操作(无论读写)都会自动授予 2. 多个会话可同时持有,与 S/X/U 等数据锁兼容 3. 仅与 Sch-M 锁(架构修改锁)互斥 4. 操作完成后立即释放,几乎无性能开销 |
2. 排他类锁(仅允许单个会话持有,阻塞所有其他锁)
| 锁类型标识 | 锁名称 | 核心用途 | 关键特性 |
|---|---|---|---|
| X | 排他锁(Exclusive Lock) | 保护数据修改操作(INSERT/UPDATE/DELETE),防止并发修改数据 |
1. 同一资源仅能被一个会话持有 X 锁 2. 与所有其他锁(S/U/Sch-S 等)都互斥 3. 阻塞所有读、写操作,持有至事务提交/回滚 4. 数据修改时自动授予,无需显式指定 |
| Sch-M | 架构修改锁(Schema Modification Lock) | 保护对象架构修改操作,确保架构修改期间无其他会话访问该对象 | 1. 执行 ALTER TABLE/DROP TABLE/RENAME TABLE 等操作时授予 2. 排他锁,与所有锁(包括 Sch-S 锁)互斥 3. 阻塞该对象的所有读写操作,操作完成后释放 4. 优先级极高,通常会等待现有锁释放后再授予 |
3. 特殊功能锁(介于共享与排他之间,解决特定场景问题)
| 锁类型标识 | 锁名称 | 核心用途 | 关键特性 |
|---|---|---|---|
| U | 更新锁(Update Lock) | 用于更新操作的前期锁定(先查后改场景),防止死锁 | 1. 执行 UPDATE 时,先对目标资源授予 U 锁,确认需要修改后升级为 X 锁 2. 同一资源仅能被一个会话持有 U 锁(互斥),与 S 锁兼容,与 X/U 锁互斥 3. 避免多个会话同时持有 S 锁后升级为 X 锁导致的死锁 4. 持有至事务提交/回滚或升级为 X 锁 |
| IX | 意向排他锁(Intent Exclusive Lock) | 标识会话意向 对某个资源的下级粒度(如表→行)持有 X 锁,用于快速锁检测 |
1. 对下级资源加 X 锁前,先对上级资源加 IX 锁(如更新某行前,先对表加 IX 锁) 2. 与 S/IS 锁互斥,与 IX/U 等锁兼容 3. 仅用于锁层级检测,不直接阻塞数据操作 4. 自动授予,无需显式控制 |
| IS | 意向共享锁(Intent Shared Lock) | 标识会话意向 对某个资源的下级粒度持有 S 锁,用于快速锁检测 |
1. 对下级资源加 S 锁前,先对上级资源加 IS 锁(如查询某行前,先对表加 IS 锁) 2. 与大多数锁(S/IS/IX/U 等)兼容,仅与 X/Sch-M 锁互斥 3. 无实际阻塞作用,仅用于锁层级校验 4. 自动授予,操作完成后快速释放 |
| IU | 意向更新锁(Intent Update Lock) | 标识会话意向 对某个资源的下级粒度持有 U 锁,是 U 锁的意向锁 |
1. 对下级资源加 U 锁前,先对上级资源加 IU 锁 2. 兼容性与 IX 锁类似,与 S/IS 锁兼容,与 X/Sch-M 锁互斥 3. 仅用于锁层级管理,日常场景中较少直接观测到 |
| BU | 大容量更新锁(Bulk Update Lock) | 用于大容量数据加载操作(如 BULK INSERT),提高批量操作性能 |
1. 仅在启用 TABLOCK 提示或批量加载选项时授予 2. 同一表可被多个会话持有 BU 锁(相互兼容),与 S 锁兼容,与 X/Sch-M 锁互斥 3. 阻塞普通写操作,不阻塞批量加载操作和读操作 4. 大幅提升大容量数据插入的性能,减少锁竞争 |
| RangeS-S | 范围共享-共享锁(键范围锁) | 用于可序列化隔离级别下的范围查询,防止幻读 | 1. 锁定查询结果的键范围及对应数据,防止其他会话插入/修改该范围内的数据 2. 共享锁特性,多个会话可同时持有,与 X 锁互斥 3. 仅在可序列化隔离级别下生效,是防止幻读的核心锁 4. 持有至事务结束 |
| RangeS-U | 范围共享-更新锁(键范围锁) | 用于可序列化隔离级别下的范围更新查询前期锁定 | 1. 介于 RangeS-S 和 RangeX-X 之间,先锁定范围,再升级为更新锁 2. 互斥性与 U 锁类似,防止并发范围更新导致的死锁 3. 仅在可序列化隔离级别下生效 |
| RangeX-X | 范围排他-排他锁(键范围锁) | 用于可序列化隔离级别下的范围数据修改,防止范围数据被篡改 | 1. 排他性锁,锁定键范围及数据,阻塞所有对该范围的读写操作 2. 与所有键范围锁和数据锁互斥,持有至事务结束 3. 可序列化隔离级别下修改范围数据时自动授予 |
二、 按锁定资源粒度分类(锁的作用范围)
SQL Server 支持"锁升级"机制(从细粒度锁升级为粗粒度锁,减少锁资源开销),按粒度从细到粗分为:
-
行级锁(Row Lock)
- 最细粒度的锁,锁定表中的单条或多条记录(通过主键/索引定位)
- 优点:锁竞争最小,并发性能最高;缺点:锁数量过多时,消耗内存资源
- 对应锁类型:
S/X/U等,日常SELECT/UPDATE优先使用行级锁
-
页级锁(Page Lock)
- 锁定数据页(SQL Server 中一页默认8KB),包含多条行记录
- 优点:锁数量少于行级锁,内存开销小;缺点:锁竞争比行级锁高(锁定一页即锁定所有行)
- 对应锁类型:
S/X/U等,当行级锁数量过多时,会升级为页级锁
-
表级锁(Table Lock)
- 锁定整个数据表,粒度最粗
- 优点:锁管理开销最小,无需维护大量细粒度锁;缺点:锁竞争最大,并发性能最低
- 对应锁类型:
S/X/Sch-S/Sch-M/IX/IS等,锁升级的最终级别(默认行级锁数量超过5000时升级为表级锁)
-
其他粒度锁(较少见)
- 数据库锁 :锁定整个数据库(如
ALTER DATABASE操作),标识为D - 文件锁 :锁定数据库文件,标识为
F - 索引锁 :锁定索引页或索引键,标识为
I - 元数据锁 :锁定系统元数据(如系统视图),标识为
M
- 数据库锁 :锁定整个数据库(如
三、 核心补充:锁的兼容性与锁升级
1. 核心兼容性规则(关键)
- 共享类锁(
S/Sch-S/IS)之间相互兼容,可同时持有 - 排他类锁(
X/Sch-M)与所有其他锁都互斥,仅能单独持有 - 意向锁(
IX/IS/IU)仅与排他类锁互斥,与共享类锁、其他意向锁兼容 - 更新锁(
U)仅与S/IS锁兼容,与X/U/IX等锁互斥
2. 锁升级机制
- 触发条件:当单个会话对某表的行级锁/页级锁数量超过阈值(默认5000个锁),或锁资源消耗过多时,SQL Server 会自动将细粒度锁升级为表级锁
- 目的:减少锁的维护开销,降低内存占用
- 控制方式:可通过
ALTER TABLE 表名 SET LOCK_ESCALATION = {AUTO | TABLE | DISABLE}调整锁升级策略
总结
- 核心功能锁:
S(读锁)、X(写锁)、Sch-S(架构稳定)、Sch-M(架构修改)、U(更新)是日常排查的重点; - 意向锁(
IX/IS):用于锁层级检测,无直接业务影响; - 键范围锁(
RangeS-S/RangeX-X):仅在可序列化隔离级别下生效,防止幻读; - 粒度分类:行级(高并发)→ 页级 → 表级(低并发),支持自动锁升级;
- 核心规则:共享锁兼容、排他锁互斥、意向锁用于快速检测。