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

关于幻读 #16

Open
lwbaptx opened this issue Jan 19, 2024 · 1 comment
Open

关于幻读 #16

lwbaptx opened this issue Jan 19, 2024 · 1 comment

Comments

@lwbaptx
Copy link

lwbaptx commented Jan 19, 2024

https://zq99299.github.io/note-book/back-end-storage/01/04.html
《事务:账户余额总是对不上账,怎么办?》
这篇文章里面对幻读的解释是不是有问题

然后会话 A 再执行相同的插入语句时,就会报主键冲突错误,但是由于事务的隔离性,它执行查询的时候,却查不到这条 ID 为 1000 的流水,就像出现了「幻觉」一样,这就是幻读。

幻读,再执行查询的时候,应该是能查到id为1000的流水的?

@zq99299
Copy link
Owner

zq99299 commented Jan 19, 2024

https://zq99299.github.io/note-book/back-end-storage/01/04.html 《事务:账户余额总是对不上账,怎么办?》 这篇文章里面对幻读的解释是不是有问题

然后会话 A 再执行相同的插入语句时,就会报主键冲突错误,但是由于事务的隔离性,它执行查询的时候,却查不到这条 ID 为 1000 的流水,就像出现了「幻觉」一样,这就是幻读。

幻读,再执行查询的时候,应该是能查到id为1000的流水的?

我又回去看了下这篇文章,确实存在你说的问题(但是结论是对的,查不到),但是这个作者在表述的时候,感觉不是很清晰:
首先:MySQL 的幻读(Phantom Read)是指在事务中,当一个事务在读取某个范围内的数据时,另一个事务在该范围内插入了新的数据行,导致第一个事务再次读取该 范围 时,发现多了一些之前不存在的数据行(就像幻觉一样),从而产生了"幻影"。

在可重复读(Repeatable Read)隔离级别下,事务 A 开启后执行了查询操作,如果在该事务中查询 id=1 的数据发现不存在,而在事务 A 执行期间事务 B 插入了 id=1 的数据并提交了事务,那么根据可重复读隔离级别的特性,事务 A 再次查询 id=1 的数据时,仍然无法查询到

可重复读隔离级别的特点是在事务开始时创建一个一致性视图,该视图包含了事务开始时已经存在的数据快照。在整个事务期间,事务 A 将始终使用这个一致性视图来执行查询操作,而不会看到其他并发事务提交的新数据。

因此,即使在事务 A 执行期间事务 B 插入了 id=1 的数据并提交了事务,事务 A 仍然无法查询到该数据,因为它使用的是事务开始时的一致性视图,该视图不包含事务 B 提交的数据。

这个行为是为了确保在可重复读隔离级别下事务的一致性,防止幻读现象的发生

范围查询 在可重复读隔离级别下可能会出现幻读问题。当一个事务执行范围查询时,它会建立一个一致性视图来获取查询范围内的数据快照。但是,在事务执行期间,其他并发事务可能会在该范围内插入或删除数据行。

如果在事务 A 执行范围查询的过程中,事务 B 插入了新的数据行或删除了某些数据行,并且在事务 A 再次执行相同的范围查询时,发现多了或少了一些数据行,就会出现幻读现象。

幻读问题在范围查询中的典型案例是使用 WHERE 子句的范围条件,例如 "SELECT * FROM table WHERE column BETWEEN value1 AND value2"。在这种情况下,事务 A 的一致性视图无法捕捉到事务 B 插入或删除的数据行,导致事务 A 在再次执行查询时看到了新增或减少的数据行,产生了幻读。

为了解决幻读问题,可以使用锁机制或间隙锁(Gap Locks)来限制并发事务对范围内的数据进行插入或删除操作,从而确保查询的一致性

该文章在表述的时候,并没有表述很清楚,确实很疑惑

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

No branches or pull requests

2 participants