共计 2058 个字符,预计需要花费 6 分钟才能阅读完成。
Insert Intention Lock,中文咱们也称之为插入意向锁。
这个能够算是对咱们之前所讲的 Gap Lock 的一个补充,对于 Gap Lock,如果还有小伙伴不懂,能够参考:记录锁、间隙锁与 Next-Key Locks。
1. 为什么须要插入意向锁
咱们之前曾经有 Gap Lock 了,Gap Lock 能够帮咱们在肯定水平上解决幻读问题,然而,之前的仿佛有点问题。
假如我有如下一张表:
CREATE TABLE `user` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `age` (`age`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
id 是主键自增;age 是一个一般索引,当初表中有如下数据:
假如我想执行如下的插入 SQL:
begin;
insert into user(username,age) values('wangwu',95);
留神,这个 SQL 执行了然而事务还没有提交。
依照咱们之前学习的对于 Gap Lock 的常识剖析一下,此时间隙锁的范畴是 (89,99),意思是这个范畴的 age 都不能够插入。
如果是这样的话,小伙伴们会发现数据插入的效率可就太低了,很容易产生锁抵触,那么怎么办?
咱们明天要介绍的插入意向锁就是用来解决这个问题的。
2. 什么是插入意向锁
咱们来看看 MySQL 官网的介绍:
An insert intention lock is a type of gap lock set by INSERT operations prior to row insertion. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6, respectively, each lock the gap between 4 and 7 with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other because the rows are nonconflicting.
大抵翻译下一下就是这样:
插入意向锁是一种在 INSERT 操作之前设置的一种间隙锁,插入意向锁示意了一种插入用意,即当多个不同的事务,同时往同一个索引的同一个间隙中插入数据的时候,它们相互之间无需期待,即不会阻塞(要是单纯依照之前间隙锁的实践,必须要等一个间隙锁开释了,下一个事务才能够往雷同的间隙处插入数据)。假如有值为 4 和 7 的索引记录,当初有两个事务,别离尝试插入值为 5 和 6 的记录,在取得插入行的排他锁之前,每个事务应用插入意向锁锁定 4 和 7 之间的间隙,然而这两个事务不会互相阻塞,因为行是不抵触的。
这就是插入意向锁。
3. 实际
小伙伴们留神,松哥之前和大家聊 Gap Lock,说过这个是可反复读(REPEATABLE READ)这个隔离级别下特有的产物,那么当初 Insert Intention Lock 是一种非凡的 Gap Lock,当然也是在可反复读这个隔离级别下失效。
接下来咱们通过两个个简略的案例来演示一下插入意向锁。
3.1 案例一
咱们的表构造以及数据和第一大节统一。
首先咱们在会话 A 中,执行如下代码:
当初会话 A 中的事务没有提交。
接下来咱们在会话 B 中,也执行一个插入操作:
咱们发现会话 B 也能够失常执行,没有产生阻塞。
这阐明,两个插入意向锁之间是兼容的,能够共存的。
3.2 案例二
咱们再来看一个不兼容的例子。
首先在会话 A 中执行如下 SQL 查问 age 大于 80 的记录,并增加排他锁:
接下来在会话 B 中,执行如下代码插入一行数据:
小伙伴们看到,这个操作会被阻塞!阻塞的起因在于,插入意向锁和排他锁之间是互斥的。
趁着产生阻塞的这会,在会话 C 中,咱们通过在后面文章中所应用的 show engine innodb status\G
指令,来查看下加锁的状况,重点看 TRANSACTION 节点:
在输入的内容中,红色框选中的中央,分明的表明了插入意向锁的存在。
4. 小结
总结一下:
- 插入意向锁尽管名字中有动向二字,但实际上是一个非凡的间隙锁。
- 插入意向锁之间不互斥。
- 插入意向锁和排他锁之间互斥。
好啦,有问题欢送留言探讨。