幻读场景
| 事务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文章中有详细的介绍
版权声明:本文为jiexiu4617原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。