知识卡片
可重复读这个术语在不同数据库里指代完全不同的保证
内容
[[快照隔离靠MVCC事务ID可见性规则实现读不阻塞写]]是一个对只读事务尤其有用的隔离 级别,但各个数据库给它起的名字五花八门、彼此矛盾。Oracle把它叫”可串行化”(实际上 只是快照隔离,比真正的可串行化弱得多),PostgreSQL和MySQL把它叫”可重复读”,IBM DB2则用”可重复读”这个名字指代真正的可串行化。这种混乱的根源在于SQL标准根本没有 “快照隔离”这个概念——标准沿用的是System R 1975年定义的隔离级别体系,那时候快照 隔离还没被发明出来,标准里定义的是”可重复读”,表面上看起来和快照隔离相似,于是 PostgreSQL和MySQL为了能”声称自己标准兼容”,就把自家的快照隔离级别命名为”可重复读”。 更糟的是,SQL标准对隔离级别的定义本身模糊、不精确,不同数据库即使都自称实现了 “可重复读”,实际提供的保证也存在很大差异——学术文献里有可重复读的正式定义,但大多 数商业实现根本不满足这个正式定义。结论是:没有人能仅凭”这个数据库支持可重复读/ 可串行化”这个名字就准确判断它实际提供了什么保证,唯一可靠的做法是查阅具体数据库 的文档、甚至直接做实验验证,不能依赖隔离级别的名称本身。这个案例是一个更通用的 警示:标准化术语在跨厂商实现里出现语义漂移是真实存在的风险,尤其是涉及并发/一致性 这类容易产生歧义的领域。
参考来源
- 位置:《数据密集型应用系统设计》第七章《事务》"可重复读与命名混淆"(源文件:
_epub-src/ch7_split_002.html)
- 结论依据:原文说明Oracle称快照隔离为可串行化、PostgreSQL和MySQL称为可重复读、
IBM DB2用可重复读指代真正的可串行化,根源是SQL标准没有快照隔离概念、标准对
隔离级别的定义本身模糊不精确,直接支撑本卡片对术语混乱的结论。
- 原始内容:在Oracle中称为可串行化的,在PostgreSQL和MySQL中称为可重复读……这种
命名混淆的原因是SQL标准没有快照隔离的概念……不幸的是,SQL标准对隔离级别的
定义是有缺陷的……最后,IBM DB2使用"可重复读"来引用可串行化。结果,没有人真正
知道可重复读的意思。