mysql间隙锁怎么用 mysql临键锁和间隙锁的区别

关于MySQL的幻读问题,看这一篇就够了

什么是幻读?

成都创新互联公司是一家集网站设计制作、成都网站制作、网站页面设计、网站优化SEO优化为一体的专业网络公司,已为成都等多地近百家企业提供网站建设服务。追求良好的浏览体验,以探求精品塑造与理念升华,设计最适合用户的网站页面。 合作只是第一步,服务才是根本,我们始终坚持讲诚信,负责任的原则,为您进行细心、贴心、认真的服务,与众多客户在蓬勃发展的市场环境中,互促共生。

幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。

首先快照读是不存在幻读的,只有当前读(实时读)才存在幻读的问题。

幻读有什么问题?

select ...for update语句就是将相应的数据行锁住,但是如果存在幻读,就把for update的语义破坏了。

如何解决幻读?

产生幻读的原因是,行锁只能锁住行,但是新插入记录这个动作,要更新的是记录之间的“间隙”。因此,为了解决幻读问题,InnoDB只好引入新的锁,也就是间隙锁(Gap Lock)。间隙锁和行锁合称 next-key lock , 每个next-key lock是前开后闭区间 。

总结

mysql要加上nextkey锁,语句该怎么写

如果在transaction1(Tr1)进行一个

select * from table1 where id 4 lock in share mode.

这里会在table1上加一个next_key lock(间隙锁),基本原理是什么呢?大致是这样的,内存中有一个lock hash。是一个key(类似于tableid+pageid+offset)到value(所加的锁)--- 这就是行锁的原理。所以 id4的话,会给0 1 2 4(假设当前数据库没有3)加上行锁,这样就保证了不会出现插入id=3.5这种事情的发生。

mysql锁算法的底层实现?

Record Lock: 单个行记录上的锁

Gap Lock :间隙锁,锁定一个范围,但不包含记录本身

Next-Key Lock:Gap Lock + Record Lock,锁定一个范围,并且包含记录本身

Record Lock会锁住索引记录,如果建表时没有设置添加索引,Innodb会去锁定隐式的主键。

mysql死锁场景整理

本文死锁场景皆为工作中遇到(或同事遇到)并解决的死锁场景,写这篇文章的目的是整理和分享,欢迎指正和补充,本文死锁场景包括:

注 :以下场景隔离级别均为默认的Repeatable Read;

前提 :表 t_user 的 uid 字段创建了唯一索引,并拥有可更新字段age。

场景复现 :

相应业务案例和解决方案 :

该场景常见于事务中存在for循环更新某条记录的情况,死锁日志显示 lock_mode X locks rec but not gap waiting (即行锁而非间隙锁),解决方案:

表结构 :

场景复现 :

首先查询表中目前存在的记录:

执行两个事务的操作:

死锁原因分析 :

解决方案 :

t_user结构改造为:

场景复现操作(几率不高) :

假设存在以下数据 :

死锁分析 :

事务1 :

① 锁住zone_id=1对应的间隙锁: zoneId in (1,2)

② 锁住索引zone_id=1对应的主键索引行锁id = [1,2]

③ 锁住uid=1对应的间隙锁: uid in (1, 2)

④ 锁住uid=1对应的主键索引行锁: id = [1, 3]

事务2 :

① 锁住zone_id=2对应的间隙锁: zoneId in (1,2)

② 锁住索引zone_id=2对应的主键索引行锁id = [3,4]

③ 锁住uid=2对应的间隙锁: uid in (1, 2)

④ 锁住uid=2对应的主键索引行锁: id = [2, 4]

解决方案 :创建联合索引,使执行计划只会用到一个索引。

测试表结构 :

场景复现操作 :

解决办法:尽量避免这种插入又回滚的场景。

避免死锁的原则:


文章名称:mysql间隙锁怎么用 mysql临键锁和间隙锁的区别
文章分享:http://scyanting.com/article/hjspec.html