9.4. 可串行化隔离级别

可串行化(Serializable) 提供最高级别的事务隔离。 这个级别模拟串行的事务执行, 就好象事务将被一个接着一个那样串行的,而不是并行的执行。 不过,使用这个级别的应用必须准备在串行化失败的时候重新发动事务.

当一个事务处于可串行化级别, 一个 SELECT 查询只能看到在事务开始之前提交的数据而永远看不到未提交的 数据或事务执行中其他并行事务提交的修改。 (不过,SELECT 的确看得到同一次事务中 前面的更新的效果.即使事务还没有提交也一样.) 这个行为和读已提交级别是不太一样的,读已提交看到的是 该事务开始时的快照,而不是该事务内部当前查询开始时的快照.

如果一个正在执行一个 UPDATE 语句(或者 DELETE 或者 SELECT FOR UPDATE 的查询返回的目标行正在被另一个并行的未提交的事务更 新,那么第二个试图更新此行的事务将等待另一个事务的提交或者回卷。 如果发生了回卷,等待中的事务可以继续修改此行。如果发生一个并行的 事务的提交,一个可串行化的事务将回卷,并返回下面信息。

ERROR:  Can't serialize access due to concurrent update
    
因为一个可串行化的事务在 可串行化事务开始之后不能更改被其他事务更改过的行。

当应用收到这样的错误信息时,它应该退出当前的事务然后从头开始重新 进行整个事务.第二次运行时,该事务看到的前一次提交的修改是该数据库 初始的样子中的一部分,所以把新版本的行作为新事务更新的起点不会有 逻辑冲突. 请注意只有更新事务才需要重试 --- 只读事务从来没有串行化冲突.

可串行化事务级别提供了严格的保证:每个事务都看到一个完全完整的数据库 的视图.不过,如果并行更新令数据库不能维持串行执行的样子,那么应用 必须准备重试事务,而且重做复杂的事务的开销可能是非常可观的.所以我们 只建议在更新查询中包含足够复杂的逻辑,在读已提交级别中可能导致错误 的结果的情况下才使用.