一个事务读到了其他事务尚未提交的写入。
举例说明脏读
事务 B 修改了 x,在事务 B 提交之前,事务 A 读到了 x 修改后的数据。这时事务 B 回滚了,相当于事务 A 读到了一个无效的数据(未实际提交到数据库中的数据),事务 A 的读就是脏读。
时间顺序Session ASession B1begin;begin;2update t1 set c1 = 'B' where id = 13select * from t1 where id = 14commit;5rollback;不可重复读
一个事务内,多次读取同一个记录的结果不一样。(一个事务能够读到另一个事务对同一个记录的修改)
举例说明不可重复读
事务 A 读取了 x,然后事务 B 修改了 x 并提交。这时事务 A 再次读取 x,发现两次读取同一个记录的结果不一样,这就是不可重复读。
时间顺序Session ASession B1begin;该事务设置自动提交2select * from t1 where id = 1(此时读到 A)3update t1 set c1 = 'B' where id = 14select * from t1 where id = 1(此时读到 B)update t1 set c1 = 'C' where id = 15select * from t1 where id = 1(此时读到 C)更新丢失
两个事务同时执行“读-修改-写回”操作序列,事务 A 覆盖了 事务 B 的写入,但又没有包含 事务 B 的修改,最终导致了部分更新数据发生了丢失。
举例说明更新丢失
事务 A 先读取某记录,然后事务 B 再读取某记录,事务 B 修改并写回,紧接着 事务 A 修改并写入。事务 A 覆盖了 事务 B 的写入,但又没有包含 事务 B 的修改,最终导致事务 B 的更新丢失了。
时间顺序Session ASession B1begin;begin;2select * from t1 where id = 1;3select * from t1 where id = 14update t1 set col1 = 2 where id = 1;5update t1 set col1 = 3 where id = 1;幻读
一个事务内,多次读取满足指定条件的数据,读出来的结果不一样(一个事务能够读到另一个事务创建的满足条件的记录)
举例说明幻读
事务 A 读取一组满足条件 1 的数据,之后事务 B 创建了满足条件 1 的数据,使其满足条件 1 并提交,如果事务 A 用相同的 条件 1 再次读取,得到一组不同于第一次读取的数据。这就叫幻读。
时间顺序Session ASession B1begin;该事务设置自动提交2select * from t1 where id > 03insert into t1 values(B)4select * from t1 where id > 0(能读到 B)不可重复读和幻读都是一个事务内,多次执行相同的查询,结果不一样。那两者有什么区别呢?
如果业务中不能接受不可重复读,那么隔离级别要在“可重复读”隔离级别或者以上。
在 MySQL 种,可重复读隔离级别即快照级别隔离。快照级别隔离的总体想法是:每个事务总是在某个时间点的一致性快照中读取数据。
为了实现快照级别隔离, MySQL 数据库采用了一种被称为多版本并发控制(MultiVersion Concurrency Control,MVCC)的机制。
防止更新丢失