脏读:
有个英雄表如下图所示
第一天 小张 往里面插入数据:
1 | BEGIN; |
小张还没有提交事务的时候,小李对数据表进行了访问,小张看到的结果如下
小李读到了小张还没有提交的数据,我们称之为“脏读”
不可重复读
小张想查看 id=1 的英雄是谁,于是他进行了 SQL 查询:
1 | SELECT name FROM heros_temp WHERE id = 1; |
然而此时,小李开始了一个事务操作,他对 id=1 的英雄姓名进行了修改,把原来的“张飞”改成了“张翼德”:
1 | BEGIN; |
然后小张再一次进行查询,同样也是查看 id=1 的英雄是谁:
运行结果:
这个时候你会发现,两次查询的结果并不一样。小张会想这是怎么回事呢?他明明刚执行了一次查询,马上又进行了一次查询,结果两次的查询结果不同。实际上小张遇到的情况我们称之为“不可重复读”,也就是同一条记录,两次读取的结果不同。
幻读
小张想要看下数据表里都有哪些英雄
这时当小张执行完之后,小李又开始了一个事务,往数据库里插入一个新的英雄“吕布”
1 | BEGIN; |
小张这时忘记了英雄都有哪些,又重新执行了一遍查询:
他发现这一次查询多了一个英雄,原来只有 3 个,现在变成了 4 个。这种异常情况我们称之为“幻读”。
总结
- 脏读:读到了其他事务还没有提交的数据。
- 不可重复读:对某数据进行读取,发现两次读取的结果不同,也就是说没有读到相同的内容。这是因为有其他事务对这个数据同时进行了修改或删除。
- 幻读:事务 A 根据条件查询得到了 N 条数据,但此时事务 B 更改或者增加了 M 条符合事务 A 查询条件的数据,这样当事务 A 再次进行查询的时候发现会有 N+M 条数据,产生了幻读。