数据库系统工程师 · 高频练习

两个事务更新不同记录却共同破坏约束,为什么属于写偏差?

中级 单选题 第 931 题 中等 数据库系统工程师Snapshot Isolation写偏差并发控制可串行化
题目

值班表要求至少一名医生保持 on_call=true。事务 T1 和 T2 在同一快照中都看到对方仍在值班,随后 T1 把医生甲改为 false,T2 把医生乙改为 false。两事务更新不同记录并都成功提交,最终无人值班。该现象属于()。

A 脏读
B 不可重复读
C 写偏差(Write Skew)
D 丢失更新
题目类型:原创高频练习题 用途:用于帮助理解数据库系统工程师相关考点和答案解析,不等同于官方真题。
正确答案
C
答案解析

两个事务基于各自一致快照做出判断,分别写不同记录,因此简单的同一行写冲突检测没有阻止提交;但组合后的结果破坏跨行约束,这正是快照隔离下典型的写偏差。

选项分析

A

错误。两个事务读取的是已提交快照,没有读取另一事务尚未提交的数据。

B

错误。题目重点不是同一事务两次读取结果变化,而是跨记录约束被并发提交破坏。

C

正确。事务写不同记录、各自检查通过,合并结果却违反业务不变量。

D

错误。没有一个事务的同一行更新被另一个覆盖,故不是典型丢失更新。

本题为什么容易错

看到“并发写”就选丢失更新是最常见误判。判断前先问:两边是不是改同一个数据项,还是分别改不同数据却共享一个条件。

先看结论

简短答案

两个事务更新不同记录却共同破坏约束,为什么属于写偏差,正确答案是 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 读取同一快照、分别更新不同医生记录,因此都可能提交;合并结果却违反至少一人值班的约束。这是写偏差,不是同一行被覆盖的丢失更新。