该篇谈谈 意向锁。
InnoDB supports multiple granularity locking which permits coexistence of row locks and table locks.For example, a statement such as LOCK TABLES ... WRITE takes an exclusive lock (an X lock) on the specified table.
To make locking at multiple granularity levels practical, InnoDB uses intention locks.
Intention locks are table-level locks that indicate which type of lock (shared or exclusive) a transaction requires later for a row in a table.
翻译:
InnoDB支持多粒度锁,允许行锁和表锁共存。
例如,LOCK TABLES之类的语句。。。WRITE在指定的表上采用独占锁(X锁)。
为了实现多粒度级别的锁定,InnoDB使用了意向锁。
意向锁是表级锁,用于指示事务稍后对表中的行需要哪种类型的锁(共享或独占)。
看这些文字,感觉就是比较模糊, 那么我认为我应该写一点小白文,能让大家稍微理解一下。
1.意向锁是表级锁。
但是 这个意向锁是个特殊的表级锁,由存储引擎去维护, 它不跟行锁冲突,意向锁直接也不冲突因为引擎级别的特殊表级概念。
2.我们要清楚 正常的表锁和行锁是冲突的。
那么如果一个事务 A 对 用户表内数据 进行了 行锁排他锁操作;
事务B去获取这个用户表的写锁 排他锁时,第一步回去检测这个用户表是否上了表锁,如果没有,就会去检测这个用户表内数据有行锁锁定操作,导致 表&行锁冲突(如果存在冲突,就会进入等待行锁释放)。
问题就是在这, innodb 有行锁,有表锁,都支持。
如果说按照上面的例子,用户表 确实没有上 表锁锁定, 但是上了行锁锁定。
所以事务B为了检测里面是否真的有行锁锁定, 会对用户表做 行遍历,去找每一行是不是都没锁定操作,这样才能 获取表级写锁。
这样看上去效率就很低。
所以设计者 搞出了意向锁。
当一个事务A 准备对 用户表进行 行级锁定操作,InooDB 会先获取该数据行所在的表的对应意向锁,进行意向锁锁定操作。
这样事务B过来尝试对 用户表做表锁锁定操作时,申请锁资源时,只需要看下 用户表是否存在 意向锁锁定 ,如果有,直接去等待资源就行,这样就不需要遍历了(以免遍了N久才知道有冲突,还是需要等待)。
理解了这个意向锁的作用后,我们再来回归意向锁的一些介绍。
意向锁 分两种:
意向共享锁 (IS)
意向排他锁(IX)
我们对某个表 做行锁操作时, 行锁也分 S锁和 X锁 (上一篇我们有说到)。
所以,innodb引擎 在知道我们对某个表数据准备使用 S (共享读锁,我上篇有讲过的)行级锁定时,就会去对这些行 所在的表,做 意向共享锁 (IS) 锁定操作。
同样,innodb引擎 在知道我们对某个表数据准备使用X (排他写锁,我上篇有讲过的)行级锁定时,就会去对这些行 所在的表,做 意向排他锁(IX)锁定操作。
最后放出一个小表格,结束我们的意向锁简单介绍篇(看久了都快不认识兼字了):
(简单总结就是,意向锁互相不冲突。 意向锁和表级锁之间的冲突,满足我上一篇所说的 共享读锁和排他写锁之间的冲突规则)
标题 | 意向共享锁(IS) | 意向排他锁(IX) | 表级共享锁(S) | 表级排他锁(X) |
意向共享锁(IS) | 兼容 | 兼容 | 兼容 | 不兼容 |
意向排他锁(IX) | 兼容 | 兼容 | 不兼容 | 不兼容 |
表级共享锁(S) | 兼容 | 不兼容 | 兼容 | 不兼容 |
表级排他锁(x) | 不兼容 | 不兼容 | 不兼容 | 不兼容 |
ps:
小明:教练,我想 上意向锁!
教练:搞不了,咱们自己是搞不了的!(存储引擎隐式操作意向锁)
大家简单了解完意向锁之后,有没有提炼出这个设计的精髓呢? 然后再细细想想,其他技术框架或者解决方案上是否也许也是有这种思想?
好吧,这篇就到这吧。