You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL Server中重现LCK_M_IX锁?解析其产生原因与本质

如何重现SQL Server的LCK_M_IX锁及锁的本质分析

一、LCK_M_IX锁的本质

LCK_M_IX是意向排他锁,属于SQL Server多粒度锁机制里的表级(或页级)锁,核心是个“信号锁”:

  • 它会告诉其他事务:当前事务已经在该表的某个行/页上持有排他锁(X),或者即将去申请行/页级的排他锁
  • 它本身不会阻塞常规的查询、单条更新操作,只会拦截需要获取整张表排他锁的操作(比如ALTER TABLE、全表锁写操作)
  • 它是SQL Server自动隐式添加的,不需要手动指定

二、快速重现LCK_M_IX锁的步骤

1. 准备测试表

先创建一张带主键的测试表,确保行级锁能正常生效:

CREATE TABLE TestLock (ID INT PRIMARY KEY, Value VARCHAR(50));
INSERT INTO TestLock VALUES (1, '初始值');

2. 会话1:开启事务并持有行级排他锁

打开第一个SQL Server查询窗口,执行以下语句(不要提交或回滚事务):

BEGIN TRAN;
-- 更新某一行,此时该行会被加X锁,SQL Server自动在表级加IX锁
UPDATE TestLock SET Value = '已更新' WHERE ID = 1;

3. 会话2:查询表级锁信息

打开第二个查询窗口,执行锁查询语句,过滤目标表的锁:

SELECT 
    resource_type,  -- 锁的层级(OBJECT=表,KEY=行)
    request_mode,   -- 锁模式(IX=意向排他,X=排他)
    resource_description
FROM sys.dm_tran_locks
WHERE resource_associated_entity_id = OBJECT_ID('TestLock');

执行后就能看到一条resource_type为OBJECT、request_mode为IX的记录,这就是你要找的LCK_M_IX锁。同时还能看到行级的KEY类型、X模式的锁。

另一种重现场景:插入行不提交

会话1执行插入语句不提交,同样会触发表级IX锁:

BEGIN TRAN;
INSERT INTO TestLock VALUES (2, '新行');
-- 不提交事务

再用会话2的查询语句,依然能抓到表级IX锁。

三、LCK_M_IX锁的产生原因

SQL Server采用多粒度锁层级(表→页→行),意向锁的设计是为了避免低效的冲突检查:

  • 如果没有意向锁,当一个事务要申请整张表的排他锁时,需要遍历表中所有行/页的锁来确认冲突,大表上会极慢
  • 意向锁(包括IX、IU、IS)相当于在表/页级提前标记“已有事务在下层持有锁”,其他事务要申请表级锁时,直接看表级的意向锁就能快速判断冲突
  • 当事务在某个行/页上持有排他锁(X),或者显式/隐式申请行/页级排他锁时,SQL Server会自动在上级层级(表/页)添加对应的意向排他锁(IX)

内容的提问来源于stack exchange,提问作者kosnkov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:05:19