脏读
- 一个事务访问到了其他事务未提交的数据更改
例:事务A对一个数据进行了修改操作,但事务A未提交,事务B在查询时却查到了修改后的数据。
脏数据:事务B查询到事务A修改后的数据,但是事务A回滚了,此时事务B查询出来的数据就是脏数据。
幻读
- 在一个事务中进行了两次查询操作,得到的行数不一致
例:一个事务进行两次查询操作,在两次查询之间,另一个事务插入了新数据并提交事务,导致第二次查询多了一条数据。
不可重复读
- 在一个事务中进行了两次查询操作,得到的数据内容不一致
例:事务A进行两次查询操作,在两次查询之间,事务B对事务A所查询的数据进行了修改操作并提交事务,导致事务A第二次查询出的数据内容与第一次查询不一致。
注:不可重复读类似于幻读,但幻读针对的是插入操作(数据行数变更),不可重复的针对的是更新操作(数据内容变更)。
解决方法
- 读已提交隔离级别可以解决脏读问题
- 可重复读隔离级别可以解决不可重复读问题
- Innodb可重复读隔离级别可以解决部分幻读问题
注:Innodb实现的可重复读隔离级别解决了查询操作时的幻读问题,但没有解决更新操作时的幻读问题。原因是Innodb在可重复读隔离级别下,只有select时会使用快照读,其他update、insert、delete语句使用的是当前读。
- 为什么Innodb要这样设计?
答:假设事务A要update一行记录,在事务A刚开始时,事务B已经delete这条记录并且提交事务了,如果update使用的是快照读,那么事务A就不知道这条记录已被删除了,会继续对这条已被删除的记录进行修改,进而产生冲突,所以进行update的时候必须要获取最新的数据,即使用当前读。