脏写:A事务对一条数据修改,但未提交,B事务再次修改这条数据,A事务发生回滚,根据undolog恢复数据,B事务写的数据丢失了,发生了脏写。
脏读:A事务对一条数据修改,但未提交,B事务读到这条修改后的数据,A事务进行回滚。B事务读到的是一条脏数据,产生脏读。
不可重复读:在一个A事务中多次读取同一条记录,其它事务在A事务提交前多次修改这条记录并提交,A读到了不同的值,称为不可重复读。
幻读:一个事务在前后两次查询同一个范围的时候、后一次查询看到了前一次查询未看到的行。幻读强调的是一个事务按照相同的SQL查询了记录之后,后续的结果中出现了之前结果中不存在的值。

 

解决以上问题:

脏读脏写:read committed(读已提交),事务只能读到已经提交的事务,也就避免了事务回滚带来的脏写、脏读问题。

不可重复读:将隔离级别提升到repeatable read(可重复读)。

幻读:RR隔离级别下为了解决“幻读”问题:“快照读”依靠MVCC控制;“当前读”通过间隙锁解决;

"""

现在你知道了,产生幻读的原因是,行锁只能锁住行,但是新插入记录这个动作,操作的是锁住的行之间的 “间隙”。因此,为了解决幻读问题,InnoDB 只好引入新的锁,也就是隙锁 (Gap Lock)。

这样,当你执行 select * from user where name = 'Jack' for update 的时候,就不止是给数据库中已有的 n 个记录加上了行锁,还同时加了 n + 1 个间隙锁(这两个合起来也成为 Next-Key Lock 临键锁)。也就是说,在数据库一行行扫描的过程中,不仅扫描到的行加上了行锁,还给行两边的空隙也加上了锁。这样就确保了无法再插入新的记录。

"""

 

 

先对“幻读”做出如下解释:

在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此, 幻读在“当前读”下才会出现(insert、update、delete,for update表示当前读);

幻读总结:
RR隔离级别下间隙锁才有效,RC隔离级别下没有间隙锁;
RR隔离级别下为了解决“幻读”问题:“快照读”依靠MVCC控制,“当前读”通过间隙锁解决;
间隙锁和行锁合称临键锁(next-key lock),每个next-key lock是前开后闭区间;
间隙锁的引入,可能会导致同样语句锁住更大的范围,影响并发度。