MySQL 幻读问题

承接上文MySQL多版本并发控制MVCC实现原理

幻读现象

MySQL 幻读问题_第1张图片

因为在RR(可重复读)隔离级别里,事务1的第二次查询没有生成新的readview,而是用的第一次查询时生成的readview,所以第二次查询返回2条数据,而不是3条数据,这就是幻读现象。​

MySQL 幻读问题_第2张图片

事务1第二次查询返回2条数据,但更新的时候,却有3条数据被更新。

select 执行的是快照读(某个版本数据的Read View),而update 执行的是当前读(最新的数据,即最新的Read View,因此更新了三条数据)。

幻读问题产生的本质原因是:如果事物中操作的都是快照读,那么是不会产生幻读问题的。

但是当快照读和当前读一起使用的时候才会产生幻读问题,因为执行了一个update操作,即用了当前读,此时读取的数据是不一致的,就产生了幻读的问题。

唤读问题的解决

在查询的时候通过加锁来解决幻读问题,

MySQL 幻读问题_第3张图片

select for update,事务1不提交,事务2的插入操作会一直阻塞。

MySQL 幻读问题_第4张图片

加锁是为了解决幻读问题,并不是说实际操作中一定要加锁,加不加锁取决于实际需求。

一般情况下select * from ....where ...是快照读,不会加锁。

而 for update,lock in share mode,update,delete都属于当前读。

当前读和快照读跟隔离级别没有关系。

锁是加在索引上的。

for update是排他锁,lock share mode叫共享锁,那什么叫间隙锁?

MySQL 幻读问题_第5张图片

1是记录锁或行锁,(1,3)是间隙锁,(1,3]是临键锁(左开右闭)。

因此可以发现,MVCC + 锁共同实现了隔离级别。

你可能感兴趣的:(平凡人笔记,mysql,数据库,java,幻读)