Closed lwbaptx closed 3 days ago
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)来限制并发事务对范围内的数据进行插入或删除操作,从而确保查询的一致性
该文章在表述的时候,并没有表述很清楚,确实很疑惑
https://zq99299.github.io/note-book/back-end-storage/01/04.html 《事务:账户余额总是对不上账,怎么办?》 这篇文章里面对幻读的解释是不是有问题
幻读,再执行查询的时候,应该是能查到id为1000的流水的?