什么是幻读?
事务隔离级别为可重复读时,
幻读发生在当前读和快照读混合使用的情况下
select * from table,正常查询为快照读
select * from table for update, 或者insert,delete等为当前读
如果事务中仅存在快照读,则不会发生幻读的情况;
测试如下:
事务1中仅快照查询,则事务2提交事务后,事务2中插入的数据事务1依然查询不到,即快照读不存在幻读
事务1 | 事务2 | |
---|---|---|
开启事务 | 开启事务 | |
select | select | 都查询不到数据 |
insert | 都查询不到数据 | |
select | select | 事务1查询不到,事务2查询到一条数据 |
事务提交 | ||
select | 事务2提交事务后,事务1依然查询不到 |
当前读混合快照读,存在幻读;事务2提交后,快照读查询不到事务2的数据,当时当前读能查询到事务2的数据
,当前读发生后,再次执行快照读,则能查询到事务2的数据;即快照读是以事务中最新一次当前读为基础的
事务1 | 事务2 | |
---|---|---|
select | select | 都查询不到数据 |
insert 1 | ||
select 1 | 数据1查询不到 | |
update 1 | 数据1不能被更新,因为事务2给数据1加了读锁,事务1超时 | |
提交事务 | ||
update 1 | 事务2提交事务后,则事务1更新数据1成功 | |
select 1 | 事务1查询到数据1 |