Skip to content
难度基础(★)
建议时长45分钟

3.8.3 并发问题

本课核心知识点整理
本课核心知识点手绘流程图(SVG)

三类并发异常的共同点

并发异常都来自事务交错执行,并且至少有两个事务访问同一数据项。区别在于冲突发生在哪个环节:写覆盖写、两次读之间被改,还是读到了未提交数据。

并发问题核心特征一句话识别
丢失修改/丢失更新两个事务都修改同一数据,后写覆盖前写写写覆盖
不可重复读同一事务两次读同一数据,中间被别人修改两次读不一样
读脏数据读到别人未提交、后来可能回滚的数据读到无效中间值

丢失修改:后写覆盖前写

设数据 A=10。两个事务都先读到 10:

步骤T1T2A 的结果
1read(A=10)10
2read(A=10)10
3A=A-5; write(A=5)5
4A=A-8; write(A=2)2

T1 的修改结果 5 被 T2 基于旧值计算出的 2 覆盖了。它的问题不在“读了未提交数据”,而在多个事务都写同一数据,前一次写回被后一次写回抹掉。

不可重复读:两次验算不一致

不可重复读强调“重复读”。事务 T1 先读数据并做一次计算,准备稍后再读一次验证;中间 T2 修改并提交了数据,导致 T1 第二次读到的值不同。

步骤T1T2
1read(A=20)
2read(A=20); A=A+50; write(A=70); commit
3read(A=70)

T1 两次读取同一数据,结果从 20 变成 70,验算失败,这就是不可重复读。它通常涉及另一个事务已经提交的修改。

读脏数据:读到后来被回滚的值

脏数据是未提交事务产生的中间数据。若 T1 修改 A 后尚未提交,T2 读取了这个修改值;随后 T1 回滚,T2 读到的值就变成了数据库中从未真正成立过的无效数据。

步骤T1T2
1read(A=20); write(A=50)
2read(A=50)
3rollback; A 恢复为 20

字幕提醒:看到 ROLLBACK,要警惕读脏数据。因为被读走的中间值可能随回滚消失。

三者对比

对比点丢失修改不可重复读读脏数据
主要冲突写-写读-写-读写未提交-读-回滚
是否强调两次读
是否强调回滚通常否
典型关键词覆盖、丢失更新验算不一致、再次读取不同未提交、回滚、脏数据

做题路线

  1. 先标出 readwritecommitrollback
  2. 两个事务都写同一数据且后写覆盖前写,判丢失修改。
  3. 同一事务两次读同一数据结果不同,判不可重复读。
  4. 读到了另一个事务未提交且后来回滚的数据,判读脏数据。

例题

单选
一个事务读取了另一个事务尚未提交的数据,这属于:
单选
两个事务先后修改同一数据,后一次修改覆盖前一次修改,属于:

自查要点

  1. 丢失修改和不可重复读的区别是什么?
  2. 读脏数据为什么和提交状态有关?
  3. 判断并发异常时应先标出哪些操作?