深度解读MySQL意向锁的工作原理机制与应用场景

意向锁

意向锁的概念

意向锁是InnoDB自动添加的一种锁,不需要用户去干预。

是数据库中的一种表级锁,一个事务要给一个资源加锁时,必须要先获取到对应类型的意向锁之后,才可以给这个资源加上自己想要的共享锁或者排他锁(不论是行级还是表级的共享/排他锁,都是需要先获取到意向共享/排他锁)。

意向锁并不是真正的锁,而是为了协调事务对表中行的锁定请求而引入的一个概念。

意向锁业的两个类型

意向共享锁(Intention Shared Lock,IS锁): 表示事务有获取到表的表级或行级共享锁的意向。

意向排他锁(Intention Exclusive Lock,IX锁): 表示事务有获取到表的表级或行级排它锁的意向。

注意:获取意向锁只是表示事务有获取到共享锁和排它锁的意向意图,而不是表示获取了意向锁,就是实际锁定了任何行或表。

意向锁是互相兼容的,不会互斥。

说明案例

前提:

如果事务A需要修改user表的id(有索引)为 '1' 的数据行,则事务A会给这行数据加上一个行级排他锁,和一个意向排他锁。

场景一:

此时如果事务B想修改user表的name(无索引)为 '张三' 的数据行,则事务B就需要给user表加上表级排他锁,但是在获取表级排他锁之前,还需要获取意向排他锁,然后就发现已经有事务A获取了意向排他锁,则事务B可以直接阻塞等待了,不再需要往下尝试判断能否获取到表级排他锁。

意向锁通过这种前置判断的操作,很好的解决了行锁与表锁共存时的事务隔离性问题。

场景二:

此时如果事务B想修改user表的id(有索引)为 '2' 的数据行,则事务B就需要先获取意向排他锁,虽然此时事务A已经持有了user表的意向排他锁,但是事务B仍旧可以去获取user表的意向排他锁,因为 ++意向锁是互相兼容的,不会互相排斥++ (上文也有说到),获取到意向排他锁之后,再去判断id为2的数据行是否有共享锁和排他锁,发现没有,则事务B持有到user表id为2的数据行的行级排他锁。

总结

行表头为事务A已经获取的锁

列表头为事务B能否获取的锁

意向共享锁 意向排他锁 表级共享锁 表级排他锁 行级共享锁 行级排它锁
意向共享锁 兼容 兼容 兼容 不兼容 兼容 不兼容
意向排他锁 兼容 兼容 不兼容 不兼容 不兼容 不兼容
表级共享锁 兼容 不兼容 兼容 不兼容 兼容 不兼容
表级排他锁 不兼容 不兼容 不兼容 不兼容 不兼容 不兼容
行级共享锁 兼容 额外讨论-1 兼容 不兼容 兼容 同行不兼容 不同行兼容
行级排它锁 额外讨论-2 额外讨论-1 不兼容 不兼容 同行不兼容 不同行兼容 同行不兼容 不同行兼容

额外讨论-1

事务A获取了 意向排他锁 ,事务B能否获取 行级共享锁行级排他锁 需要继续往下去判断,判断事务A的排他锁是表锁还是行锁,

如果是表锁,则事务B不能再加行级共享锁;

如果是行锁,则继续判断事务B要加行级共享锁的行是否被事务A或其他事务加了行级排它锁,如果加了,则事务B不能再加行级共享锁,如果这一行没加行级排他锁,则事务B可以加上行级共享锁(行锁:同行不兼容,不同行兼容)。

额外讨论-2

事务A获取了 意向共享锁 ,事务B能否获取 行级排他锁 需要继续往下去判断,判断事务A的共享锁是表锁还是行锁,

如果是表锁,则事务B不能再加行级排他锁;

如果是行锁,则继续判断事务B要加行级排他锁的行是否被事务A或其他事务加了行级共享锁,如果加了,则事务B不能再加行级排他锁,如果这一行没加行级共享锁,则事务B可以加上行级排他锁(行锁:同行不兼容,不同行兼容)。

关注我,我将持续输出Java常用相关技术文章。

相关推荐
好记忆不如烂笔头abc10 分钟前
统计信息的导出导入
数据库
Casual_Lei35 分钟前
Neo4j
数据库·oracle·neo4j
IT枫斗者42 分钟前
集合工具类
java·linux·数据库·windows·算法·microsoft
大厂小码哥1 小时前
图解Redis 01 | 初识Redis
数据库·redis·缓存
咚咚?2 小时前
麒麟操作系统 MySQL 主从搭建
数据库·mysql
爬山算法3 小时前
Oracle(130)如何启动和关闭Oracle数据库?
数据库·oracle
天荒地老笑话么4 小时前
MySQL——数据库的高级操作(三)权限管理(1)MySQL 的权限
数据库·mysql
计算机学姐8 小时前
基于python+django+vue的二手电子设备交易平台
开发语言·vue.js·后端·python·mysql·django·web3.py
天荒地老笑话么8 小时前
MySQL——数据库的高级操作(二)用户管理(1)uer表
数据库·mysql
GG编程8 小时前
Mysql 索引
数据库·mysql