知识卡片

多对象事务的必要性外键非规范化文档与二级索引一致性

普通读书笔记卡

内容

不少分布式数据存储直接放弃了多对象事务,因为它难以跨分区实现、且在追求高可用/ 高性能时容易碍事,但这不代表多对象事务不重要——原文明确说,在分布式数据库里实现 事务并没有什么根本性障碍。判断是否需要多对象事务,要看应用是否需要协调写入多个 不同对象,这类场景至少有三类:一是关系模型(或图模型)里存在外键/边这类跨记录 引用,插入几条互相引用的记录时,必须确保这些引用始终有效、彼此一致;二是文档模型 虽然把需要一起更新的字段收纳进同一个文档、天然不需要多对象事务,但缺乏连接能力 会反过来鼓励非规范化(比如把未读邮件数缓存成单独字段),一旦需要更新这类非规范化 信息,就必须一次性更新多个文档,此时事务能防止这些冗余数据彼此失步;三是任何带 二级索引的数据库,每次改值都要同步更新索引,从事务视角看索引是独立的数据库对象, 没有隔离性保证的话,一条记录可能出现在某个索引里、却还没出现在另一个索引里。这些 场景理论上都能不靠事务实现,但代价是:没有原子性,错误处理会复杂得多(写到一半 出错,谁去清理不一致的残留状态?);没有隔离性,会直接暴露出各种并发问题(正是 本章后续要详细讨论的内容)。

参考来源

- 位置:《数据密集型应用系统设计》第七章《事务》"多对象事务的需求"(源文件: _epub-src/ch7_split_001.html) - 结论依据:原文说明多对象事务用于保证外键/边引用的有效性、防止非规范化文档 数据不同步、保持二级索引与主数据一致,并明确指出没有原子性错误处理更复杂、 没有隔离性会导致并发问题,直接支撑本卡片结论。 - 原始内容:多对象事务使你确保这些引用始终有效……当需要更新非规范化的信息时…… 需要一次更新多个文档。事务在这种情况下非常有用……从事务角度来看,这些索引是 不同的数据库对象……没有事务,错误处理就要复杂得多,缺乏隔离性,就会导致并发 问题。