问题引出

我之前的一篇博客 数据库并发不一致分析 有提到过事务隔离级别以及相应加锁方式、能够解决的并发问题。

标准情况下,在 RR(Repeatable Read) 隔离级别下能解决不可重复读(当行修改)的问题,但是不能解决幻读的问题。

而之前有看过一篇 mysql 加锁的文章 MySQL 加锁处理分析,里面有提到一点:

对于Innodb,Repeatable Read (RR) 针对当前读,RR隔离级别保证对读取到的记录加锁 (记录锁),同时保证对读取的范围加锁,新的满足查询条件的记录不能够插入 (间隙锁),不存在幻读现象。

那么问题来了,到底 Innodb 中 RR 隔离级别是否能解决幻读呢?

在 MySQL 加锁处理分析这篇文章下面的评论中,有这样的一个交流:

ontheway
弱弱地问一句,我看的书里面都说的是RR隔离级别不允许脏读和不可重复读,但是可以幻读,怎么和作者说的不一样呢?

hedengcheng(作者)
你说的没错,因此我在文章一开始,就强调了这一点。mysql innodb引擎的实现,跟标准有所不同。

求证官方文档

MySQL Innodb 引擎的实现,跟标准有所不同,针对这个问题,我表示怀疑,于是查看 mysql 官方文档关于 RR的解释,里面有这么一段话:

For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and DELETE statements, locking depends on whether the statement uses a unique index with a unique search condition, or a range-type search condition. For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it. For other search conditions, InnoDB locks the index range scanned, using gap locks or next-key locks to block insertions by other sessions into the gaps covered by the range.

大致意思就是,在 RR 级别下,如果查询条件能使用上唯一索引,或者是一个唯一的查询条件,那么仅加行锁,如果是一个范围查询,那么就会给这个范围加上 gap 锁或者 next-key锁 (行锁+gap锁)。

从这句话的理解来看,和文章里的解释一样,由于 RR 级别对于范围会加 GAP 锁,这个和 sql 的标准是有一些差异的。

其他解释

后面又发现了一篇文章 Understanding InnoDB transaction isolation levels,文章中又提到:

This isolation level is the default for InnoDB. Although this isolation level solves the problem of non-repeatable read, but there is another possible problem phantom reads.

大概意思是,RR 能解决不可重复读的问题,但仍可能发生幻读,怀疑作者并不了解 Innodb 的特殊实现,评论中也有提到:

Do you mean 'write skew' instead of 'phantom reads'? The 'repeatable read' in SQL standard allows 'phantom reads', however, since InnoDB uses next-key locking this anomaly does not exist in this level. Looks like it's equivalent to 'snapshot isolation' in Postgres and Oracle.

再来看一篇文章 MySQL的InnoDB的幻读问题,这里面提供了一些例子,还没来得及分析,但最后的结论是:

MySQL InnoDB的可重复读并不保证避免幻读,需要应用使用加锁读来保证。而这个加锁度使用到的机制就是next-key locks。

最终结论

Innodb 的 RR 隔离界别对范围会加上 GAP,理论上不会存在幻读,但是是否有例外呢,这个还需要进一步求证。

最新文章

  1. Opserver开源的服务器监控系统(ASP.NET)
  2. 条形码的应用三-----------从Excel文件中读取条形码
  3. linux命令详解:md5sum命令
  4. jquery元素插入、删除、清空
  5. 24. Longest Consecutive Sequence
  6. 1.Nexus安装与配置
  7. 把vector中的string对象导入到字符指针数组中
  8. Mybatis SqlSessionTemplate 源码解析
  9. JAVA组程序优化综合考试试题
  10. 关于iOS9中配置App Transport Security(应用程序传输安全协议)
  11. linux性能优化
  12. hdoj 1599 find the mincost route【floyd+最小环】
  13. asp.net实现 EXCEL数据导入到数据库功能
  14. css3 动画运动路径
  15. HTML与DOM BOM javascript
  16. classmethod 和 staticmethod
  17. Oracle数据库中字符型字段按数字排序
  18. Linux 第八天
  19. volatile 关键字了解与使用
  20. 教你一步步composer安装Magento2.3

热门文章

  1. linux服务器项目部署【完整版】
  2. Linux命令集锦
  3. ubuntu解决网易云无法打开
  4. 用kubeadm构建k8s集群部署
  5. C语言实现 "谁是凶手?"
  6. golang 并发执行函数func类型slice
  7. SpaceVim 语言模块 erlang
  8. springboot与activemq的使用
  9. DE1-SOC工程helloworld-第一篇(未完成)
  10. spark 执行架构