MySQL InnoDB引擎处于可重复的阅读级别。是否有解决幻影阅读的问题?在互联网上有不同的意见,有人说他们已经解决了,有人说他们没有解决,甚至某些Big V的观点也无法达成统一。
让我们今天对其进行分析,并完全解决这种幻想的问题。
在解决幻影阅读问题之前,普及了一些知识点。
首先创建一个用户表以进行数据验证:
并发交易将导致以下三个问题:
定义:一项交易读取其他交易中未提交的数据。
从上面的示例图中可以看出,交易2后的数据被修改并且没有提交。Affairs1已读取最新的事务2的修改数据,即肮脏的读数。
定义:一项交易读取由其他交易修改的数据。
从上面的示例图中可以看出,在将数据2修改并提交到交易之后。事务1查询1已读取事务2的最新数据,在这种情况下这是不可用的。
定义:一项交易读取其他交易插入的最新数据。
从上面的示例图中可以看出,在将数据2插入并提交到交易之后。事务1的第二查询1读了交易2中插入的最新数据,这是一种幻觉。
传递明确的阅读和当前阅读。
快照阅读:读取数据的历史版本,而不是锁定数据。
例如:选择
当前读数:阅读最新版本的数据并锁定数据。
例如:插入,更新,删除,选择以进行更新,在共享模式下选择锁定。
在可重复的读取中,它是否解决了隔离级别的幻影阅读问题?
只能说幻想阅读问题的一部分。
首先,在明确阅读的情况下,通过MVCC解决了幻影阅读的问题(重复使用阅读视图)。
如果您想了解有关MVCC并阅读视图的更多信息,则可以关闭文章。
将MySQL的隔离级别设置为重复阅读:
执行测试案例并验证它:
从上面的示例图中可以看出,事务1的两个查询与获得的结果的结果是一致的,并且找不到事务2插入的最新数据。
原因是在重复阅读级别中,在读取第一个快照时会生成阅读视图。当我读取第二个快照时,重复了第一个循环读取视图,因此获得的结果两次是一致的。
因此,在明确阅读的情况下,重复阅读隔离水平可以解决幻影读数的问题。
再次测试。在当前的阅读中,您可以反复阅读隔离水平是否解决了幻影阅读的问题:
从上面的示例图中可以看出,交易的两个查询1获得了结果。插入数据2并提交交易后。当当前的交易1(添加供更新)读取时,请阅读插入的最新数据通过交易2。
原因是,在重复阅读的级别下,当前阅读的每次执行都会产生新的阅读视图,因此您可以阅读其他事务中插入的最新数据。
因此,在目前的阅读中,对隔离水平的重复读取并未解决幻觉阅读的问题。
当我执行上述测试案例时,我突然想到了一个问题。由于当前对更新选择的读数存在幻想问题,因此其他当前读取是否会重新阅读幻想问题,例如插入。
执行测试案例并验证它:
如预期的那样,在插入当前的读数的情况下,还有一个幻影读数的问题(主要关键冲突)。
有什么办法?当您可以反复阅读隔离级别并执行当前阅读时,您可以解决幻影阅读的问题吗?
当然,唯一的方法是锁定。
执行第一个查询时,交易1被锁定(用于更新)以防止其他交易修改数据,这将完全解决幻影读数的问题。
您认为有一个好方法吗?