InnoDB可重复读隔离级别下如何避免幻读

InnoDB可重复读隔离级别下如何避免幻读

  • 表象:快照读(非阻塞读)–伪MVCC
  • 内在:next-key锁(行锁+gap锁)

next-key锁(行锁+gap锁)

  • 行锁
  • Gap锁

对主键索引或者唯一索引会用Gap锁吗

  • 如果where条件全部命中,则不会用Gap锁,只会加记录锁

在这里插入图片描述

  • 如果where条件部分命中或者全不命中,则会加Gap锁

在这里插入图片描述

session1
select @@tx_isolation;
start transaction;
delete from tb where id = 9;
rollback;
delete from tb where id = 7; //删除一个不存在的id


session2
select @@tx_isolation;
start transaction;
insert into tb values('i',10);
rollback;
insert into tb values('i',8); //插入不存在的值

我们进行删除不存在的id的时候,周围的数也被blok住了,说明gap锁是有范围的。

session1
select * from tb where id in(5,7,9) lock in share mode;

在这里插入图片描述
在事务未提交前。

session2
insert into tb values('i',4);//成功
insert into tb values('ii',7);//不成功,被blok住了
insert into tb values('ii',8);//不成功,被blok住了
insert into tb values('ii',10);//成功

这次我们来精确命中全部数据

session1
select * from tb where id in (5,6,9) lock in share mode;

session2
insert into tb values("ii",7);//成功的
insert into tb values("iii",8);//成功执行

Gap锁会在非唯一索引或者不走索引的当前读中

  • 非唯一索引
    在这里插入图片描述

在这里插入图片描述

session1
delete from tb1 where id = 9;

session2
insert into tb1 values('test',9);
#6-11之间会被blok
insert into tb1 values('test',5);
insert into tb1 values('test1',7);//被blok住了,说明有间隙锁
insert into tb1 values('test1',12);

我们再细节一点

insert into tb1 values('bb',6); //成功了,叶子节点按照首字母b排序的
insert into tb1 values('dd',6); //不成功
  • 不走索引
    在这里插入图片描述
    创建tb2
    在这里插入图片描述
    id是没有任何索引的一个列
#5-11开外
insert into tb2 values('test',2);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值