在一个稳定版本视图中读取
事务在快照上读取时,后续并发提交不必立刻改变它所见的数据。多版本存储保留所需的旧版本,使同一事务可以继续依照既定视图查询,而不是每条语句都换成最新提交状态。
PostgreSQL 18把Repeatable Read的实现称为快照隔离:其快照从事务第一条非事务控制语句开始,同时查询仍能看到本事务先前的修改。产品的精确快照建立时机需要按文档确认,不能只凭名称推断。
同一记录冲突与跨记录依赖
快照不是允许任意覆盖旧数据。PostgreSQL在该级别中若要修改被并发事务更新并提交的目标行,可以报告并发更新失败,让当前事务撤销并从头重试,而不是直接沿旧视图写回。
不过,两个事务也可能各自读取一组数据,再写入不同记录,两者都避开直接写写冲突,却得到不能由任何串行顺序解释的组合。文档中的分组求和后向另一组插入结果,便展示稳定快照仍可能发生序列化异常。
参考:[1]
隔离级别名称不能代替机制
SQL隔离级别名称规定的最低保护,与产品采用的具体实现不总相同。PostgreSQL文档明确指出,其他系统可能把Repeatable Read与Snapshot Isolation作为不同级别提供,因此不宜把它们在所有数据库中画等号。
要求可串行化时,还需要检测或阻止使事务无法串行解释的依赖。PostgreSQL的Serializable在相似快照之上增加有关监测,并可能终止某个事务;这是额外的一致性要求,不是把快照保留得更久就自然获得的性质。
参考:[1]