如何解决幻读_什么是幻读

什么是幻读

1. 举个例子

定义表结构如下:

CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `c` (`c`)
) ENGINE=InnoDB;
 
insert into t values(0,0,0),(5,5,5),
(10,10,10),(15,15,15),(20,20,20),(25,25,25);
7d91353ea34c40831f1ceeecd11466cf.png
  • T1 时刻查询到的数据为id=5这行数据
  • T2 时刻将id=0的数据的d置为5
  • T3 时刻查询到的数据为id=0,id=5的数据
  • T4时刻插入新的数据 (1,1,5)
  • T5时刻查询到的数据为id=0,id=1,id=5,

其中T5时刻查询到了id=1的现象称为幻读,而查到id=0不能称为幻读。这是因为幻读的定义为幻读指的是两次查询同一个范围的数据,后一次查询到了前一次没有查询到的数据,就好像出现了幻觉,所以称为幻读。需要注意的是,幻读只有在当前读的时候才会出现,而且幻读专指新插入的行

2. 幻读带来的问题

  • 破坏了锁的语义。当实行 select ... from... where ... for update 的时候,语义是要锁住符合条件的行,但是幻读破坏了这个规则。
  • 数据不一致。两次同样的范围查询却查出来的结果不一样。

3. 如何解决幻读

答案是使用间隙锁。在两两数据行之间有间隙,如果我们能把数据行之间的间隙也锁住,则不会有产生幻读的数据插入。

间隙锁和行锁合称为next-key lock ,实现语句为 select * from t for update。这样表t中数据行被锁住,而且行与行之间的间隙也会被锁住。

4. next-key lock 带来的问题

next-key lock 会导致锁的范围变大,影响并发,而且有可能会带来死锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值