在讲解以前,先来思考一个问题——假设有用户表结构以下:html
MySql,InnoDB,Repeatable-Read:users(id PK, name, age KEY)mysql
id | name | age |
---|---|---|
1 | Mike | 10 |
2 | Jone | 20 |
3 | Tony | 30 |
首先事务 A
插入了一行数据,而且没有 commit
:sql
INSERT INTO users SELECT 4, 'Bill', 15;
复制代码
随后事务 B
试图插入一行数据:并发
INSERT INTO users SELECT 5, 'Louis', 16;
复制代码
请问:post
事务 B
是否会被事务 A
阻塞?在了解插入意向锁以前,强烈建议先了解一下意向锁
和间隙锁
:ui
首先让咱们来看一下 MySql 手册 是如何解释 InnoDB 中的插入意向锁
的:spa
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.code
插入意向锁
是在插入一条记录行前,由 INSERT 操做产生的一种间隙锁
。该锁用以表示插入意向,当多个事务在同一区间(gap)插入位置不一样的多条数据时,事务之间不须要互相等待。假设存在两条值分别为 4 和 7 的记录,两个不一样的事务分别试图插入值为 5 和 6 的两条记录,每一个事务在获取插入行上独占的(排他)锁前,都会获取(4,7)之间的间隙锁
,可是由于数据行之间并不冲突,因此两个事务之间并不会产生冲突(阻塞等待)。htm
总结来讲,插入意向锁
的特性能够分红两部分:索引
插入意向锁
是一种特殊的间隙锁
—— 间隙锁
能够锁定开区间内的部分记录。插入意向锁
之间互不排斥,因此即便多个事务在同一区间插入多条记录,只要记录自己(主键
、惟一索引
)不冲突,那么事务之间就不会出现冲突等待。须要强调的是,虽然插入意向锁
中含有意向锁
三个字,可是它并不属于意向锁
而属于间隙锁
,由于意向锁
是表锁而插入意向锁
是行锁。
如今咱们能够回答开头的问题了:
插入意向锁
与记录锁
。事务 A
不会阻塞事务 B
。若是只是使用普通的间隙锁
会怎么样呢?仍是使用咱们文章开头的数据表为例:
MySql,InnoDB,Repeatable-Read:users(id PK, name, age KEY)
id | name | age |
---|---|---|
1 | Mike | 10 |
2 | Jone | 20 |
3 | Tony | 30 |
首先事务 A
插入了一行数据,而且没有 commit
:
INSERT INTO users SELECT 4, 'Bill', 15;
复制代码
此时 users
表中存在三把锁:
记录锁
。间隙锁
。间隙锁
。最终,事务 A
插入了该行数据,并锁住了(10,20)这个区间。
随后事务 B
试图插入一行数据:
INSERT INTO users SELECT 5, 'Louis', 16;
复制代码
由于 16 位于(15,20)区间内,而该区间内又存在一把间隙锁
,因此事务 B
别说想申请本身的间隙锁
了,它甚至不能获取该行的记录锁
,天然只能乖乖的等待 事务 A
结束,才能执行插入操做。
很明显,这样作事务之间将会频发陷入阻塞等待,插入的并发性很是之差。这时若是咱们再去回想咱们刚刚讲过的插入意向锁
,就不难发现它是如何优雅的解决了并发插入的问题。
Repeatable-Read
的事务隔离级别下,使用插入意向锁
来控制和解决并发插入。插入意向锁
是一种特殊的间隙锁
。插入意向锁
在锁定区间相同但记录行自己不冲突的状况下互不排斥。