值班表要求至少一名医生保持 on_call=true。事务 T1 和 T2 在同一快照中都看到对方仍在值班,随后 T1 把医生甲改为 false,T2 把医生乙改为 false。两事务更新不同记录并都成功提交,最终无人值班。该现象属于()。
两个事务基于各自一致快照做出判断,分别写不同记录,因此简单的同一行写冲突检测没有阻止提交;但组合后的结果破坏跨行约束,这正是快照隔离下典型的写偏差。
选项分析
错误。两个事务读取的是已提交快照,没有读取另一事务尚未提交的数据。
错误。题目重点不是同一事务两次读取结果变化,而是跨记录约束被并发提交破坏。
正确。事务写不同记录、各自检查通过,合并结果却违反业务不变量。
错误。没有一个事务的同一行更新被另一个覆盖,故不是典型丢失更新。
本题为什么容易错
看到“并发写”就选丢失更新是最常见误判。判断前先问:两边是不是改同一个数据项,还是分别改不同数据却共享一个条件。
简短答案
两个事务更新不同记录却共同破坏约束,为什么属于写偏差,正确答案是 C(写偏差(Write Skew))。两个事务基于各自一致快照做出判断,分别写不同记录,因此简单的同一行写冲突检测没有阻止提交;但组合后的结果破坏跨行约束,这正是快照隔离下典型的写偏差。
易混淆概念对比表
| 概念 | 本题判断 | 区别要点 | 记忆提示 |
|---|---|---|---|
| 脏读 | 本题干扰项 | 错误。两个事务读取的是已提交快照,没有读取另一事务尚未提交的数据。 | 看到该词不要急着选,先判断是否真正解决题干问题 |
| 不可重复读 | 本题干扰项 | 错误。题目重点不是同一事务两次读取结果变化,而是跨记录约束被并发提交破坏。 | 看到该词不要急着选,先判断是否真正解决题干问题 |
| 写偏差(Write Skew) | 本题正确答案 | 正确。事务写不同记录、各自检查通过,合并结果却违反业务不变量。 | 看到题干核心场景时优先联想到它 |
| 丢失更新 | 本题干扰项 | 错误。没有一个事务的同一行更新被另一个覆盖,故不是典型丢失更新。 | 看到该词不要急着选,先判断是否真正解决题干问题 |
本题易混淆选项怎么区分
- 脏读:错误。两个事务读取的是已提交快照,没有读取另一事务尚未提交的数据。
- 不可重复读:错误。题目重点不是同一事务两次读取结果变化,而是跨记录约束被并发提交破坏。
- 丢失更新:错误。没有一个事务的同一行更新被另一个覆盖,故不是典型丢失更新。
知识点详解
快照隔离让事务读取开始时的一致快照,并常通过写写冲突避免同一行被并发覆盖,但它不天然保证所有执行都等价于某个串行顺序。写偏差发生在多个事务依据重叠条件读取数据,却修改不同记录,最终共同破坏约束。可选防护包括使用数据库真正的可串行化隔离、对代表业务约束的记录加锁、重新设计约束落点,或采用数据库支持的冲突检测机制;具体方案要结合产品语义。
备考速记
同一行互相覆盖像丢失更新;不同人各改一行却把规则一起改坏,是写偏差。
Snapshot Isolation 在可串行化场景中的作用
Snapshot Isolation在本题中的核心价值,是解决“值班表要求至少一名医生保持 on_call=true。事务 T1 和 T2 在同一快照中都看到对方仍在值班,随后 T1 把医生甲改为 false,T2 把医生乙改为 false。两事务更新不同记录并都成功提交,最终无人值班。该现象属于()”这个场景问题。复习时不要只背选项名称,还要理解它为什么适用于该场景,以及它能解决哪类安全、流程或管理问题。
同类题怎么考
- 医生值班、账户限额、会议室容量等跨记录约束场景。
- 比较脏读、不可重复读、丢失更新与写偏差的触发条件。
Snapshot Isolation 在数据库系统工程师软考中的考法
软考选择题通常不会只考概念定义,还会把Snapshot Isolation放到可串行化场景中,要求判断它的作用、适用范围或与相近概念的区别。遇到这类题时,先抓住题干中的业务场景,再看哪个选项最能解决该场景下的核心问题。
解题思路
先别被“两个事务都写了”带偏,要看它们写的是不是同一行。这里 T1 改甲、T2 改乙,行级写冲突可能完全碰不上;问题出在两人都依据旧快照相信“对方还在”。把两个提交结果合起来,至少一人值班的约束才被破坏。这就是写偏差,而不是后写覆盖前写的丢失更新。
考点定位
写偏差和丢失更新的关键区别是:丢失更新通常争写同一数据项;写偏差常更新不同数据项,却共同破坏一个业务不变量。
易错提醒
- 认为快照隔离等同于所有场景下的可串行化。
- 只用单行唯一约束,却没有覆盖“至少一人值班”这样的跨行规则。
- 用普通快照读取做业务校验,却没考虑并发事务同时通过。
备考提示
- 用“读集合相交、写集合分离、组合约束失效”识别写偏差。
- 复习数据库具体实现时,再核对 Serializable、谓词锁或 SSI 如何处理此类冲突。
你可能还想了解
- 写偏差和丢失更新有什么区别?
- 快照隔离为什么不一定可串行化?
- 数据库怎样防止跨行约束被并发事务破坏?
本文小结
T1 和 T2 读取同一快照、分别更新不同医生记录,因此都可能提交;合并结果却违反至少一人值班的约束。这是写偏差,不是同一行被覆盖的丢失更新。