MySQL 意向锁为什么不会阻塞行锁之间的并发?

MySQL 意向锁为什么不会阻塞行锁之间的并发?

MySQL 意向锁为什么不会阻塞行锁之间的并发?

在 MySQL InnoDB 锁体系中,很多人第一次看到**意向锁(Intention Lock)**都会产生一个误解:

表上都加锁了,那是不是会影响行锁并发?

实际上:

✅ 意向锁不会阻塞行锁之间的并发

✅ 意向锁只参与表锁冲突判断

❌ 它不是用来控制行并发的锁

本文从设计背景 → 锁模型 → 执行流程 → 本质原理 → 生产实践一步一步讲清楚。


一、先说结论

意向锁存在的目的只有一个:

提高表锁与行锁冲突检测效率

而不是:

控制行锁并发


二、InnoDB 为什么需要意向锁?

因为 InnoDB 支持:

  • 表锁
  • 行锁
  • 两者同时存在

这叫:

👉 多粒度锁模型(Multi Granularity Locking)


如果没有意向锁会发生什么?

假设有人执行:

sql 复制代码
LOCK TABLE user READ;

数据库必须检查:

复制代码
这张表有没有行锁?

如果没有意向锁,就只能:

复制代码
扫描整张表的所有行锁

复杂度:

复制代码
O(行数)

有意向锁后

只需要看:

复制代码
表级有没有 IX / IS

复杂度:

复制代码
O(1)

这就是意向锁存在的根本原因。


三、意向锁是什么?

本质是一种:

👉 "声明型锁"

告诉数据库:

复制代码
我准备在某些行上加锁

而不是:

复制代码
我要锁整张表

四、意向锁类型

锁类型 含义
IS 准备加行共享锁
IX 准备加行排他锁

五、重点:意向锁不会参与行锁竞争

这是整篇文章最关键点。


行锁并发流程

事务 A

sql 复制代码
SELECT * FROM user WHERE id = 1 FOR UPDATE;

发生:

复制代码
表:加 IX
行:id=1 加 X

事务 B

sql 复制代码
SELECT * FROM user WHERE id = 2 FOR UPDATE;

发生:

复制代码
表:加 IX
行:id=2 加 X

是否冲突?

表锁层面

复制代码
IX vs IX → 兼容

行锁层面

复制代码
X(id=1) vs X(id=2) → 不冲突

最终结果

两个事务完全可以并发执行。


六、什么时候才会被阻塞?

只有在涉及表锁时。

例如:

sql 复制代码
LOCK TABLE user WRITE;

此时需要表级 X 锁。

如果已有:

复制代码
IX 表锁存在

那么:

复制代码
表X锁 ← 会被阻塞

七、兼容矩阵

IS IX S表锁 X表锁
IS
IX

八、很多人为什么会误解?

因为看到:

复制代码
行锁前 → 先加表锁(意向锁)

就以为:

复制代码
表被锁了 → 并发下降

但实际上:

意向锁不是资源锁,而是状态标记

它类似:

复制代码
元信息锁提示

而不是:

复制代码
真正锁资源

九、真正影响行并发的是什么?

在生产中真正影响并发的是:

① 行锁冲突

同一行 X vs X


② 间隙锁

范围锁定


③ Next-Key Lock

行 + 间隙组合锁


④ MVCC 可见性

版本判断导致等待


十、DBA 生产经验总结

在高并发 OLTP 场景:

几乎可以忽略意向锁性能影响

因为:

复制代码
IX 和 IX 永远兼容

只有在:

  • LOCK TABLE
  • DDL 操作
  • 元数据锁竞争

时才明显出现。


十一、底层设计哲学(非常关键)

意向锁设计思想:

👉 用极低成本解决表锁检测问题

如果没有意向锁:

复制代码
表锁检测 = 扫描所有行锁

有意向锁:

复制代码
表锁检测 = 看一个标记

十二、面试一句话总结

如果面试官问:

意向锁为什么不影响行并发?

可以回答:

意向锁只是表级声明锁,用于快速判断表锁与行锁冲突,不参与行锁资源竞争,因此不会影响行锁并发。


十三、一句话理解

记住一句话:

意向锁是给数据库看的,不是给业务并发用的。

若有转载,请标明出处:https://blog.csdn.net/CharlesYuangc/article/details/157512232

相关推荐
my_realmy13 小时前
Java SE 基础学习笔记(一):面向对象、继承多态、抽象接口与异常(JDK 8)
java·多线程·并发··生产者消费者模式
Mr.朱鹏14 小时前
Linux 服务器 LVM 根分区在线动态扩容
linux·服务器·数据库
摇滚侠14 小时前
《SpringBoot 3:入门与应用实战》第 12 章 JDBC 与事务 数据库初始化机制 阅读笔记 36
数据库·spring boot·笔记
qiuhaipeng114 小时前
Claude code 升级后上下文长度变短问题
java·前端·数据库
云贝贝贝15 小时前
腾讯云 TDSQL(MySQL 版)运维高频 6 坑:代理路由、读写分离、分片键、监控、PITR
运维·mysql·腾讯云
wxwx_bscxy32215 小时前
基于Python新冠疫情可视化分析系统的设计与实现
java·数据库·spring boot·python·微信小程序·sqlite
剑之所向16 小时前
.NET 官方`System.Threading.Channels`
前端·javascript·数据库
词却17 小时前
数据库基础:DQL 数据查询语言
数据库·oracle
昌原的儿子LEO18 小时前
Linux IO多路复用与SQLite数据库核心知识点总结
linux·数据库·oracle
山岚的运维笔记19 小时前
mysql 专业笔记 -- 第 8 章:使用变量
运维·数据库·笔记·后端·学习·mysql·dba