Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

对于“不可重复读的重点是修改,幻读的重点在于新增或者删除”存在的问题,以及幻读的理解? #1763

Open
Ligh0x74 opened this issue Jul 2, 2022 · 3 comments
Labels
question Further information is requested

Comments

@Ligh0x74
Copy link

Ligh0x74 commented Jul 2, 2022

问题描述:

  1. 在MySQL知识总结文章中,对不可重复读和幻读区别的解释与文章最后所提供的参考“技术分享 | 隔离级别:正确理解幻读:https://opensource.actionsky.com/20210818-mysql/ ”存在矛盾的问题。
    在参考文章中,对不可重复读和幻读的理解如下图所示。
    Snipaste_2022-07-02_12-09-48
    而总结正文是这样描述的。
    Snipaste_2022-07-02_12-12-49
  2. 在MySQL重要知识点->事务隔离级别(图文详解)文章中,演示了幻读出现的情况,如图所示。
    Snipaste_2022-07-02_12-16-48
    图中先使用快照读,然后使用当前读,两次结果不一致,就说是幻读。但是根据上面的参考文章, 快照读和当前读混用造成的异常,不能算是幻读。

希望答疑解惑!

@Snailclimb
Copy link
Owner

问题描述:

  1. 在MySQL知识总结文章中,对不可重复读和幻读区别的解释与文章最后所提供的参考“技术分享 | 隔离级别:正确理解幻读:https://opensource.actionsky.com/20210818-mysql/ ”存在矛盾的问题。
    在参考文章中,对不可重复读和幻读的理解如下图所示。
    Snipaste_2022-07-02_12-09-48
    而总结正文是这样描述的。
    Snipaste_2022-07-02_12-12-49
  2. 在MySQL重要知识点->事务隔离级别(图文详解)文章中,演示了幻读出现的情况,如图所示。
    Snipaste_2022-07-02_12-16-48
    图中先使用快照读,然后使用当前读,两次结果不一致,就说是幻读。但是根据上面的参考文章, 快照读和当前读混用造成的异常,不能算是幻读。

希望答疑解惑!

简单谈谈我的理解哈,欢迎一起探讨。

不可重复读和幻读有什么区别呢?

  • 不可重复读的重点是内容修改或者记录减少比如多次读取一条记录发现其中某些记录的值被修改;
  • 幻读的重点在于记录新增比如多次执行同一条查询语句(DQL)时,发现查到的记录增加了。

幻读其实可以看作是不可重复读的一种特殊情况,单独把区分幻读的原因主要是解决幻读和不可重复读的方案不一样。

举个例子:执行 deleteupdate 操作的时候,可以直接对记录加锁,保证事务安全。而执行 insert 操作的时候,由于记录锁(Record Lock)只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁(Gap Lock)。也就是说执行 insert 操作的时候需要依赖 Next-Key Lock(Record Lock+Gap Lock) 进行加锁来保证不出现幻读。

@Snailclimb Snailclimb added the question Further information is requested label Jul 10, 2022
@Sanjay10tech
Copy link

hi

@MrXionGe
Copy link
Contributor

在数据库的ACID(原子性、一致性、隔离性、持久性)特性中,不可重复读和幻读是两种由于并发事务引起的数据读取问题,它们主要发生在数据库的隔离级别设置上,尤其是在读已提交(Read Committed)和可重复读(Repeatable Read)隔离级别下。

不可重复读(Non-repeatable Read)指的是在一个事务内,多次读取同一数据集合时,由于其他事务对数据集合的修改或删除操作,导致同一事务内的多次读取结果不一致。简单来说,就是一个事务第一次读取某行数据后,另一事务修改了该数据并提交,当前事务再次读取时发现数据发生了改变。

幻读(Phantom Read)则是指在同一个事务中,多次执行相同的查询操作时,由于其他事务进行了插入操作,导致后续的查询返回了之前不存在的行。也就是说,一个事务执行了一次查询操作,得到了一组结果集,另一个事务插入了一些新行,这时原先的事务再次执行同样的查询,就会得到一个包含了新行的结果集,好像这些行是“幻影”一样突然出现。

本质区别在于:

  • 不可重复读关注的是数据行的修改或删除,即读取的数据内容发生了变化。
  • 幻读关注的是数据行数的变化,即读取的数据集合增加了新的数据行。

可以参考MySQL官方文档中的解释:
https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_non_repeatable_read
https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_phantom

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants