Innodb锁机制

Innodb锁机制,第1张

InnoDB实现了两种类型的行锁。

共享锁(S) :允许一个事务去读一行,阻止其他事务获得相同的数据集的排他锁。

排他锁(X) :允许获得排他锁的事务更新数据,但是组织其他事务获得相同数据集的共享锁和排他锁。

可以这么理解:

共享锁就是我读的时候,你可以读,但是不能写。排他锁就是我写的时候,你不能读也不能写。其实就是MyISAM的读锁和写锁,但是针对的对象不同了而已。

除此之外InnoDB还有两个表锁:

意向共享锁(IS) :表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁

意向排他锁(IX) :类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。

意向锁是InnoDB自动加的,不需要用户干预。

对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X);对于一般的Select语句,InnoDB不会加任何锁,事务可以通过以下语句给显示加共享锁或排他锁。

共享锁:select * from table_name where .....lock in share mode

排他锁:select * from table_name where .....for update

InnoDB行锁是通过给索引项加锁实现的,索引分为主键索引和非主键索引两种,如果 一条 sql语句 *** 作了主键索引,MySQL就会锁定这条主键索引如果一条语句 *** 作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引,如果没有索引,InnoDB会通过隐藏的聚簇索引来对记录加锁。也就是说:如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样。

InnoDB对于行的查询都是采用了Next-Key Lock的算法,锁定的不是单个值,而是一个范围(GAP)。上面索引值有1,3,5,8,11,其记录的GAP的区间如下:是一个 左开右闭 的空间(原因是默认主键的有序自增的特性,结合后面的例子说明)

(-∞,1],(1,3],(3,5],(5,8],(8,11],(11,+∞)

InnoDB对于行的查询都是采用了Next-Key Lock的算法,锁定的不是单个值,而是一个范围,按照这个方法是会和第一次测试结果一样。但是,当查询的索引含有唯一属性的时候,Next-Key Lock 会进行优化,将其降级为Record Lock,即仅锁住索引本身,不是范围。

Next-Key Lock是行锁与间隙锁的组合,这样,当InnoDB扫描索引记录的时候,会首先对选中的索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。如果一个间隙被事务T1加了锁,其它事务是不能在这个间隙插入记录的。

在第一个session中执行

在第二个sessio中执行

在第三个sessio中执行

可以看到二三中都在等在锁释放,这个时候在第一个session中执行

可以在二三中看到有一个

说到底还是意向锁和gap锁导致的,锁的知识另写总结吧,这里避免的话:

1 不用 insert into on duplicate key update

2 非要用insert into on duplicate key update的话,就不用rr隔离级别(没有gap锁)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7222541.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-03
下一篇 2023-04-03

发表评论

登录后才能评论

评论列表(0条)

保存