MySQL的不可重复读和幻读

本文介绍了MySQL中不可重复读和幻读问题。不可重复读是因update操作使同一事务多次查询字段值变化,幻读是insert和delete操作致数据数量不同。还阐述了解决办法,MVCC保证可重复读和避免幻读,record lock和gap lock防止幻读,完全解决幻读需显式加锁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不可重复读

     不可重复读是指在同一个事务中,两次(或以上)查询发现符合条件的数据记录的字段值发生了变化,导致不可重复读出现的原因主要是update操作

不可重复读的例子

  1. Alice和Bob开启了数据库的两个事务;
  2. Bob读取post_comment表中所有post_id为1的数据;
  3. Alice修改了post_id为1的数据;
  4. Alice提交了她的事务;
  5. 如果Bob重复读取post_id为1的数据,他将发现结果集的字段值发生了变化;

幻读

     幻读是指在同一个事务中,两次(或以上)查询同一个范围内的数据,发现数据的数量不同,导致幻读问题的原因主要是insert和delete操作

幻读的例子

  1. Alice和Bob开启了数据库的两个事务;
  2. Bob读取post_comment表中所有post_id为1的数据;
  3. Alice增加了一条post_id为1的数据;
  4. Alice提交了她的事务;
  5. 如果Bob重复读取post_id为1的数据,他将发现结果集的记录数量发生了变化;

幻读的重点在于新增或者删除
不可重复读的重点是修改

 

在MySQL中不可重复读和幻读的解决办法(在RR隔离界别中)

     MVCC(多版本并发控制)保证了数据的可重复读,也保证不会读到幻读数据(即使是有新的符合条件的数据产生,在同一个事务的下次查询中也查不到,蒙蔽自己的双眼假装看不到)

     在MySQL的InnoDB存储引擎中,MVCC普通方式(select * from table)查询数据是不加任何锁的,数据的筛选除了通过查询条件之外,还要根据数据行的隐藏字段(两个版本号)来和事务的版本号来进行比较后过滤. 这样做的好处是支持的并发量更高(因为不加锁),根据版本号来过滤数据也解决了不可重复读的问题,也能保证不会读到幻读数据

     record lock(记录锁)和gap lock(间隙锁)保证了幻读数据不会产生(在读取数据的时候加锁,防止在读取时有其他事务对读取条件内的数据做增删改操作)

     也就是说如果你要完全解决幻读问题,还要在查询语句中使用像lock in share mode和for update这样显式的加锁语句

ps: 本人新手一个,如果有什么写的不对的,希望各位大佬能帮忙指正一下,感谢

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AiIsAlive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值