内容简介:InnoDB 支持需要强调一下,意向锁是一种即:
InnoDB 支持 多粒度锁(multiple granularity locking)
,它允许 行级锁
与 表级锁
共存,而 意向锁
就是其中的一种 表锁
。
意向锁(Intention Locks)
需要强调一下,意向锁是一种 不与行级锁冲突表级锁
,这一点非常重要。意向锁分为两种:
-
意向共享锁
(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 会先获取该数据行所在在数据表的对应意向锁。
意向锁要解决的问题
我们先来看一下百度百科上对意向锁存在意义的描述:
如果另一个任务试图在该表级别上应用共享或排它锁,则受到由第一个任务控制的表级别意向锁的阻塞。第二个任务在锁定该表前不必检查各个页或行锁,而只需检查表上的意向锁。
设想这样一张 users
表:
id | name |
---|---|
1 | ROADHOG |
2 | Reinhardt |
3 | Tracer |
4 | Genji |
5 | Hanzo |
6 | Mccree |
事务 A 获取了某一行的排他锁,并未提交:
SELECT * FROM users WHERE id = 6 FOR UPDATE; 复制代码
事务 B 想要获取 users
表的表锁:
LOCK TABLES users READ; 复制代码
因为共享锁与排他锁 互斥
,所以事务 B 在视图对 users
表加共享锁的时候,必须保证:
- 当前没有其他事务持有 users 表的排他锁。
- 当前没有其他事务持有 users 表中任意一行的排他锁 。
为了检测是否满足第二个条件,事务 B 必须在确保 users
表不存在任何排他锁的前提下,去检测表中的每一行是否存在排他锁。很明显这是一个效率很差的做法,但是有了 意向锁
之后,情况就不一样了:
意向锁的兼容互斥性
意向锁是怎么解决这个问题的呢?首先,我们需要知道意向锁之间的兼容互斥性:
意向共享锁(IS) | 意向排他锁(IX) | |
---|---|---|
意向共享锁(IS) | 兼容 | 兼容 |
意向排他锁(IX) | 兼容 | 兼容 |
即 意向锁之间是互相兼容的 ,emmm......那你存在的意义是啥?
虽然意向锁和自家兄弟互相兼容,但是它会与普通的 排他 / 共享锁 互斥:
意向共享锁(IS) | 意向排他锁(IX) | |
---|---|---|
共享锁(S) | 兼容 | 互斥 |
排他锁(X) | 互斥 | 互斥 |
注意:这里的排他 / 共享锁指的都是表锁!!!意向锁不会与行级的共享 / 排他锁互斥!!!
现在我们回到刚才 users
表的例子:
事务 A
获取了某一行的排他锁,并未提交:
SELECT * FROM users WHERE id = 6 FOR UPDATE; 复制代码
此时 users
表存在两把锁: users
表上的 意向排他锁
与 id 为 6 的数据行上的 排他锁
。
事务 B 想要获取 users 表的共享锁:
LOCK TABLES users READ; 复制代码
此时 事务 B
检测事务 A 持有 users
表的 意向排他锁
,就可以得知 事务 A
必然持有该表中某些数据行的 排他锁
,那么 事务 B
对 users
表的加锁请求就会被排斥(阻塞),而无需去检测表中的每一行数据是否存在排他锁。
意向锁的并发性
这就牵扯到我前面多次强调的一件事情:
意向锁不会与行级的共享 / 排他锁互斥!!!
意向锁不会与行级的共享 / 排他锁互斥!!!
意向锁不会与行级的共享 / 排他锁互斥!!!
重要的话要加粗说三遍,正因为如此,意向锁并不会影响到多个事务对不同数据行加排他锁时的并发性(不然我们直接用普通的表锁就行了)。
最后我们扩展一下上面 users 表的例子来概括一下意向锁的作用(一条数据从被锁定到被释放的过程中,可能存在多种不同锁,但是这里我们只着重表现意向锁):
id | name |
---|---|
1 | ROADHOG |
2 | Reinhardt |
3 | Tracer |
4 | Genji |
5 | Hanzo |
6 | Mccree |
事务 A
先获取了某一行的 排他锁
,并未提交:
SELECT * FROM users WHERE id = 6 FOR UPDATE; 复制代码
-
事务 A
获取了users
表上的 意向排他锁 。 -
事务 A
获取了 id 为 6 的数据行上的 排他锁 。
之后 事务 B
想要获取 users
表的 共享锁
:
LOCK TABLES users READ; 复制代码
-
事务 B
检测到事务 A
持有users
表的 意向排他锁 。 -
事务 B
对users
表的加锁请求被阻塞(排斥)。
最后 事务 C
也想获取 users
表中某一行的 排他锁
:
SELECT * FROM users WHERE id = 5 FOR UPDATE; 复制代码
-
事务 C
申请users
表的 意向排他锁 。 -
事务 C
检测到事务 A
持有users
表的 意向排他锁 。 -
因为意向锁之间并不互斥,所以
事务 C
获取到了users
表的 意向排他锁 。 -
因为id 为 5 的数据行上不存在任何 排他锁
,最终
事务 C
成功获取到了该数据行上的 排他锁 。
以上所述就是小编给大家介绍的《详解 MySql InnoDB 中意向锁的作用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- InnoDB 并发插入,居然使用意向锁?
- 佛罗里达州一城市同意向黑客支付60万美元赎金 以恢复电脑记录
- Flutter 完整开发实战详解(十六、详解自定义布局实战)
- 数据结构 1 线性表详解 链表、 栈 、 队列 结合JAVA 详解
- 详解Openstack环境准备
- Java泛型详解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
PHP and MySQL Web Development
Luke Welling、Laura Thomson / Sams / July 25, 2007 / $49.99
Book Description PHP and MySQL Web Development teaches you to develop dynamic, secure, commerical Web sites. Using the same accessible, popular teaching style of the three previous editions, this b......一起来看看 《PHP and MySQL Web Development》 这本书的介绍吧!