MySQL教程:插入意向锁介绍。
Insert Intention Lock,中文大家也被称作插入意向锁。
这个算得上是对之前我所说的GapLock的一个补充,
1.为何需要插入意向锁
我们之前已经有GapLock了,GapLock可以帮助我们在某种程度上处理幻读难题,可是,以前的似乎有点难题。
假定我有以下一张表:
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;
假定我想执行如下的插入SQL:
begin;
insert into user(username,age) values('wangwu',95);
注意,这个SQL执行了可是事务还没有递交。
依照我们之前学习关于GapLock的知识分析一下,这时间隙锁的范围是(89,99),意思是这个范围的age都不可以插入。
如果是这样的话,朋友们会发现数据插入的效率可就太低了,很容易引发锁矛盾,那么怎么办?
我们今天要介绍的插入意向锁就是用来解决这个问题的。
2.什么叫插入意向锁
插入意向锁是一种在INSERT操作以前设定的一种间隙锁,插入意向锁表示了一种插入意图,即当多个不同的事务,同时往同一个检索的同一个间隙中插入数据的时候,它们互相之间无需等待,即不会阻塞(如果单纯依照以前间隙锁的理论,一定要等一个间隙锁释放了,下一个事务才能够往同样的间隙处插入数据)。假定有值为4和7的检索记录,现在有2个事务,各自试着插入值为5和6记录,在取得插入行的排他锁以前,每个事务使用插入意向锁锁住4和7之间的间隙,可是这俩事务不会彼此阻塞,由于行是不冲突的。
这便是插入意向锁。
3.实践
朋友们注意,松哥之前和大家聊GapLock,说过这个是可重复读(REPEA TABLE READ)这个隔离级别下独有的产物,那么现在Insert Intention Lock是一种特殊的GapLock,当然也是在可重复读这个隔离级别下起效。
接下来我们通过两个个简单的案例来演示一下插入意向锁。
3.1案例一
我们的表结构以及数据与第一小节一致。
首先大家在会话A中,执行如下代码:
如今会话A里的事务没有递交。
接下来我们在会话B中,也执行一个插入操作:
我们发现会话B也能正常执行,没有出现阻塞。
这表明,2个插入意向锁之间是适配的,能够并存的。
3.2案例二
我们再来看一个不兼容的事例。
首先在会话A中执行如下SQL查询age大于80记录,并添加排他锁:
接下来在会话B中,执行如下代码插入一行数据:
朋友们看到,这个操作会被阻塞!阻塞的原因在于,插入意向锁和排他锁之间是互斥的。
借着发生阻塞的这会,在会话C中,我们通过在前文中所使用的show engine innodb status\G命令,来查看下上锁的情况,重点看TRANSACTION节点:
在输出内容中,红色框选中的地方,清楚的表明了插入意向锁的出现。
4.总结
MySQL教程之插入意向锁总结一下:
插入意向锁尽管名字中有意向二字,可事实上是一个特殊的间隙锁。
插入意向锁之间不互斥。
插入意向锁和排他锁之间互斥。