幻读与不可重复读的区别

众所周知,数据库的四种隔离级别:未提交读,提交读,可重复读,可串行化,分别会出现:脏读,不可重复读以及幻读等问题。

脏读是非常容易理解的:事务A中未提交的修改可以被事务B读取。而不可重复读与幻读就让人非常疑惑了。

从结果上看,不可重复读与幻读都表现为:在同一事物中运行多次同样的查询语句,得到的结果不相同。

那么这两者的区别是什么呢?网上的资料一般都是说:不可重复读主要针对修改数据(也就是update和delete),而幻读的重点在于新增数据(insert)。那么究竟是什么导致他们出现这样的差别呢?

我们如果假设用锁来实现可重复读的话:事务A在读取,修改数据后就对这些数据加上了行级锁,使其他的事务无法再修改这些数据,这样就解决了不可重复读的问题。但是行级锁无法阻止数据库执行insert语句。所以,如果这时候事务B执行了一条插入语句的话,事务A再读取数据时很可能会发现多了一条符合要求的记录,这就是幻读。

幻读无法通过加行锁来避免。而可串行话隔离级别,通过在每一行数据上加锁来强制使事务串行执行,虽然可以解决幻读的问题,但却极度降低数据库性能。

所以,MySQL等数据库为了解决幻读问题又不影响数据库性能,使用了以乐观锁为理论基础的MVCC(多版本并发控制) 


书山有路勤为径 学海无涯苦作舟