Mysql意向锁
这里写目录标题
- 前置问题
- 概念
- 作用
- 兼容互斥性
- 总结
前置问题
首先我们需要问自己什么是意向锁?
为什么要有意向锁?
意向锁如何使用?
概念
mysql官网上对于意向锁的解释中有这么一句话
The main purpose of IX and IS locks is to show that someone is locking a row. or going to lock a row in the table.
意思是说加意向锁的目的是为了表明某个事务正在锁定一行或者将要锁定一行,简单概述就是要表明加锁的意图。
意向锁是一种不与行级锁冲突表级锁,这一点非常重要。意向锁分为两种:
意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S锁) 代码解读复制代码-- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
SELECT column FROM table ... LOCK IN SHARE MODE;
意向排他锁(intention exclusive lock, IX):事务有意向对表中的某些行加排他锁(X锁) 代码解读复制代码-- 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
SELECT column FROM table ... FOR UPDATE;
即:意向锁是有数据引擎自己维护的,用户无法手动操作意向锁,在为数据行加共享 / 排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁。
作用
我们从案例来理解需要意向锁存在的原因和作用。
事务A锁住了表中的一行,让这一行只能读,不能写。
之后,事务B申请整个表的写锁。
如果事务B申请成功,那么理论上它就能修改表中的任意一行,这与A持有的行锁是冲突的,数据库需要避免这种冲突,就是说要让B的申请被阻塞,直到A释放了行锁
数据库要怎么判断这个冲突呢?
step1:判断表是否已被其他事务用表锁锁表
step2:判断表中的每一行是否已被行锁锁住
注意step2,这样的判断方法效率实在不高,因为需要遍历整个表。
于是就有了意向锁。在意向锁存在的情况下,事务A必须先申请表的意向共享锁,成功后再申请一行的行锁。在意向锁存在的情况下,上面的判新可以改成
step1:不变
step2:发现表上有意向共享锁,说明表中有些行被共享行锁锁住了,因此,事务B申请表的写锁会被阻塞。
注意:申请意向锁的动作是数据库完成的,就是说,事务A申请一行的行锁的时候,数据库会自动先开始申请表的意向锁,不需要我们程序员使用代码来申请。
兼容互斥性
意向锁之间是相互兼容的,但是它会与普通的表级排他锁互斥,与普通的行级排他锁、行级共享锁是相互兼容的。
总结
意向锁是表锁,为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存。意向锁的存在是为了解决行锁与表锁共存时性能问题所产生的,是mysql内部存储引擎自己实现的不需要我们特地添加。