数据库

Oracle 的 SERIALIZABLE,其实不是可串行化

SQL 标准定义 SERIALIZABLE 的方式是:不出现脏读、不可重复读、幻读这三种现象。它没有要求调度真的可串行化。

Oracle 的 SERIALIZABLE 实际是快照隔离:每个事务读自己的快照,提交时只检查写写冲突。三种现象确实都不会出现,字面上合格。

但快照隔离挡不住写偏斜:两个医生都看到「2 人在岗」,各自请假,改的是不同的行,没有写写冲突,结果 0 人在岗。两种串行顺序都不会出现这个结果。

要挡住它,得追踪每个事务读过什么(读集)。PostgreSQL 9.1 起的 SSI(可串行化快照隔离)做了这件事,开销也更大。

所以不同数据库里,同一个名字 SERIALIZABLE,保证的东西可能不一样。

esc