MySQL 幻读问题原创
1年前
206834
幻读现象
因为在RR(可重复读)隔离级别里,事务1的第二次查询没有生成新的readview,而是用的第一次查询时生成的readview,所以第二次查询返回2条数据,而不是3条数据。
事务1第二次查询返回2条数据,但更新的时候,却有3条数据被更新,这就是幻读现象。
select 执行的是快照读(某个版本数据的Read View),而update 执行的是当前读(最新的数据,即最新的Read View,因此更新了三条数据)。
幻读问题产生的本质原因是:如果事物中操作的都是快照读,那么是不会产生幻读问题的。
但是当快照读和当前读一起使用的时候才会产生幻读问题,因为执行了一个update操作,即用了当前读,此时读取的数据是不一致的,就产生了幻读的问题。
唤读问题的解决
在查询的时候通过加锁来解决幻读问题,
select for update,事务1不提交,事务2的插入操作会一直阻塞。
加锁是为了解决幻读问题,并不是说实际操作中一定要加锁,加不加锁取决于实际需求。
一般情况下select * from ....where ...是快照读,不会加锁。
而 for update,lock in share mode,update,delete都属于当前读。
当前读和快照读跟隔离级别没有关系。
锁是加在索引上的。
for update是排他锁,lock share mode叫共享锁,那什么叫间隙锁?
1是记录锁或行锁,(1,3)是间隙锁,(1,3]是临键锁(左开右闭)。
因此可以发现,MVCC + 锁共同实现了隔离级别。
点赞收藏
分类: