幻读场景
事务A | 事务B |
---|---|
事务A按照特定的条件查询数据,查询到了2条数据 | |
事务B插入一条数据 commit | |
事务A按照原条件查询数据,查询到还是2条数据 | |
事务A修改其中一条数据的值update,看到修改的范围是3条数据 | |
事务A按照原条件查询数据,查询到3条数据 |
为什么出现幻读:主要原因是快照读和当前读混合使用
首先事务A执行了3次读取操作
第一次和第二次操作都是执行的快照读,如果是可重复读的隔离级别下。这两次读取的数据是一致的。
而 for update,lock in share mode,update,delete都属于当前读,事务执行会执行当前读,也就是会读取出事务B插入的数据
幻读解决方案:
都使用当前读或者快照读。如果有update,显然会使用当前读,所以将前面两条数据也变成当前读(对读取操作加锁 for update)
事务A | 事务B |
---|---|
select * from user where age =20 for update; | |
insert into user values(25,‘25’,20);此时会阻塞等待锁 | |
select * from user where age =20 for update; |
事务B中的insert会被阻塞,当事务A提交成功后才会执行成功。
关于当前读和快照读会在接下来的MVCC文章中有详细的介绍