丢失更新与死锁等待图

共 19 题
#

1. 丢失更新的防止,SELECT FOR UPDATE、版本号、CAS、SSI?

A FOR UPDATE、版本号、CAS、SSI 从不同角度让"读-改-写"安全 ✓ 正确答案
B 丢失更新无法防止
C 版本号无法防丢失更新
D 只能靠 FOR UPDATE
#

2. 丢失更新(Lost Update)的定义,两个事务读-改-写同一行,后写覆盖先写?

A 两个事务写不同行互相覆盖
B 丢失更新就是写偏斜
C 数据库会自动防止丢失更新
D 两个事务读-改-写同一行,后写者覆盖先写者导致更新丢失 ✓ 正确答案
#

3. 应用层乐观锁(Optimistic Locking)的实现,版本号比较?

A 更新时不校验版本
B 更新时带版本号条件,影响行数为 0 说明冲突需重试 ✓ 正确答案
C 乐观锁需要持锁
D 版本号只用于读
#

4. REPEATABLE READ 是否完全防止丢失更新?

A RR 完全防止丢失更新
B RR 只保证读一致,先快照读后写仍可能丢失更新,需加锁或版本校验 ✓ 正确答案
C RR 只影响写
D RR 下不可能丢失更新
#

5. InnoDB 死锁检测的触发与代价(等待图、victim 选择、innodb_deadlock_detect 权衡)

A 死锁检测与等待图无关
B 通过等待图环检测,选择 victim 回滚,innodb_deadlock_detect 可在死锁极少时关闭以省开销 ✓ 正确答案
C 死锁检测无开销
D 只能依靠超时
#

6. 两个并发 UPDATE 会因行锁串行化而互见结果,为什么先 SELECT 再 UPDATE 的读-改-写才是真正的丢失更新?请说明两者的本质区别。

A 两条并发 UPDATE 会因行锁串行化而互见结果,而先 SELECT 再 UPDATE 的读-改-写存在竞态窗口,是丢失更新的真正来源 ✓ 正确答案
B 两条并发 UPDATE 会互相覆盖,造成丢失更新
C 读-改-写是原子的,不会丢失更新
D UPDATE 是快照读,先 SELECT 再 UPDATE 更安全
#

7. PostgreSQL 与 MySQL 死锁检测的实现差异?

A 两者都靠等待图检测环并中止牺牲者,但检测时机与错误码不同 ✓ 正确答案
B PostgreSQL 不检测死锁
C MySQL 不检测死锁
D 两者检测机制完全相同
#

8. 等待图(Wait-for Graph)的概念,节点是事务,边是等待关系?

A 节点是锁,边是行
B 等待图无法检测死锁
C 节点是事务,边是等待关系,环表示死锁 ✓ 正确答案
D 节点是数据行
#

9. 等待图环检测算法,DFS 或 BFS 检测环?

A DFS 或 BFS/拓扑排序均可检测环,DFS 便于定位环上事务 ✓ 正确答案
B 只能用 DFS
C 无法检测环
D 环检测复杂度为 O(1)
#

10. “先读后写”的丢失更新竞态,SELECT 判断 + UPDATE 之间如何被并发破坏?原子条件更新(UPDATE ... WHERE 状态=期望值)为何是首选修复?

A 条件更新无法防丢失更新
B 条件更新只用于读
C 条件更新把判断与写入合并为一条原子语句,通过影响行数判断是否成功,消除竞态窗口 ✓ 正确答案
D 条件更新需要长事务
#

11. 从错误码与日志区分死锁(MySQL 1213 / PG 40P01)与锁等待超时(MySQL 1205),各自的重试与降级策略有何不同?

A 死锁是系统检测环后回滚(1213/40P01),锁等待超时是等待超阈值放弃(1205),重试策略不同 ✓ 正确答案
B 两者都是 1213
C 锁等待超时是死锁
D 两者无法区分
#

12. 丢失更新的发生条件,先读后写且无锁,两个事务互相覆盖?

A 需要有锁
B 先读后写且无锁,两个事务基于同一旧值写回互相覆盖 ✓ 正确答案
C 与读无关
D 只有写才会发生
#

13. 乐观锁与悲观锁解决丢失更新,版本号与 FOR UPDATE?

A 两者都持锁
B 版本号无法防丢失更新
C 乐观锁需要数据库锁
D 悲观锁用 FOR UPDATE 串行化,乐观锁用版本号校验,适用场景不同(冲突率) ✓ 正确答案
#

14. 死锁(立即回滚一个事务)与锁等待超时(innodb_lock_wait_timeout)的区别与处理

A 两者都是 1213
B 死锁是等待方超时
C 锁等待超时是死锁
D 死锁由系统检测环后回滚,锁等待超时是等待超过 innodb_lock_wait_timeout 放弃 ✓ 正确答案
#

15. 乐观锁冲突重试的设计(重试次数、退避、冲突率监控)

A 可无限重试
B 需设重试上限、加退避、监控冲突率,冲突率高时改用悲观锁 ✓ 正确答案
C 无需退避
D 重试不需要重新读取数据
#

16. 活锁(livelock)与锁饥饿和死锁有何区别?数据库如何通过锁队列公平性避免某个事务永远拿不到锁?

A 数据库无法避免饥饿
B 三者完全相同
C 死锁是循环等待,活锁/饥饿是某方总被抢先或长期等不到,锁队列公平性(FIFO)可缓解 ✓ 正确答案
D 活锁就是死锁
#

17. 如何用 SHOW ENGINE INNODB STATUS 的 LATEST DETECTED DEADLOCK 段定位死锁事务与语句?等待图与回滚选择如何体现在日志中?

A 无法用于定位
B 只显示锁的数量
C 记录死锁事务、锁等待关系、SQL 语句与 victim 选择,可用于定位死锁 ✓ 正确答案
D 不包含死锁信息
#

18. 死锁避免的工程清单,统一加锁顺序、缩短事务、索引优化与并发度控制?

A 死锁无法避免
B 索引优化与死锁无关
C 只能靠回滚
D 统一加锁顺序、缩短事务、索引优化、控制并发可系统性降低死锁 ✓ 正确答案
#

19. 死锁回滚后的事务重试如何保证幂等?重试前需要重新读取最新数据还是直接重放原 SQL?

A 重试前应重新读取最新数据,并用幂等键/唯一约束保证幂等 ✓ 正确答案
B 直接重放原 SQL 即可
C 重试不需要考虑幂等
D 无需重试上限