MySQL解决幻读——MVCC与间隙锁

本文详细探讨了MySQL中如何解决幻读问题,重点介绍了MVCC(多版本并发控制)和间隙锁在当前读与快照读中的作用。在可重复读(RR)隔离级别下,MVCC用于防止快照读的幻读,而当前读则通过间隙锁防止幻读。通过举例说明,解释了InnoDB如何使用next-key locks来避免幻读,强调在某些场景下需要手动加锁将快照读转换为当前读以完全避免幻读。建议读者参考相关官方文档以深入了解。
摘要由CSDN通过智能技术生成

当前读 与 快照读

当前读:

  select...lock in share mode (共享读锁)
  select...for update
  update , delete , insert

当前读, 读取的是最新版本, 并且对读取的记录加锁, 阻塞其他事务同时改动相同记录,避免出现安全问题。

例如,假设要update一条记录,但是另一个事务已经delete这条数据并且commit了,如果不加锁就会产生冲突。所以update的时候肯定要是当前读,得到最新的信息并且锁定相应的记录。

快照读:
简单的select操作(不包括 select … lock in share mode, select … for update)。

Read Committed隔离级别:每次select都生成一个快照读。

Read Repeatable隔离级别:开启事务后第一个select语句才是快照读的地方,而不是一开启事务就快照读。

在RR级别下,快照读是通过MVVC(多版本控制)和undo log来实现的,当前读是通过加record lock(记录锁)和gap lock(间隙锁)来实现的。

如何解决幻读

快照读的幻读是用MVCC解决的,当前的读的幻读是用间隙锁解决的。

innodb的默认事务隔离级别是rr(可重复读)。它的实现技术是mvcc该技术不仅可以保证innodb的可重复读,而且可以防止幻读。(这也就是是此前以rr隔离级别实践时,不仅可以防止可重复读,也防止了幻读)但是它防止的是快照读,也就是读取的数据虽然是一致的,但是数据是历史数据。

这个帖子里面就有一个实例:MySQL的InnoDB的幻读问题
一些文章写到InnoDB的可重复读避免了“幻读”(phantom read),这个说法并不准确。

那InnoDB指出的可以避免幻读是怎么回事呢?

以下翻译自MySQL官网文档(http://download.nust.na/pub6/mysql/doc/refman/5.5/en/innodb-next-key-locking.html),翻译水平一般,请见谅。

当隔离级别是可重复读,且禁用innodb_locks_u

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值