Redrock Postgres 搜索 英文
版本: 15 / 16 / 17

13.5. 序列化故障处理 #

可重复读取和可串行化隔离级别都可以产生旨在防止序列化异常的错误。如前所述,使用这些级别的应用程序必须准备好重试由于序列化错误而失败的事务。此类错误的消息文本会根据具体情况而有所不同,但始终具有 SQLSTATE 代码 40001 (serialization_failure)。

重试死锁失败也可能是个明智之举。这些失败具有 SQLSTATE 代码 40P01 (deadlock_detected)。

在某些情况下,对于具有 SQLSTATE 代码 23505unique_violation)的唯一键故障以及具有 SQLSTATE 代码 23P01exclusion_violation)的排除约束故障,也可以适当地进行重试。例如,如果应用程序在检查当前存储的键后为主键列选择一个新值,则可能会发生唯一键故障,因为另一个应用程序实例同时选择了相同的新键。这实际上是一个序列化故障,但服务器无法检测到它,因为它无法“查看”插入的值与先前读取之间的连接。在某些特殊情况下,即使原则上服务器有足够的信息来确定序列化问题是潜在原因,服务器也会发出唯一键或排除约束错误。虽然建议无条件地重试 serialization_failure 错误,但在重试这些其他错误代码时需要更加小心,因为它们可能表示永久错误条件,而不是瞬态故障。

重新尝试完整的交易非常重要,包括所有逻辑,这些逻辑决定要发布的 SQL 和/或要使用的值。因此,PostgreSQL 没有提供自动重试设施,因为它无法保证正确性。

事务重试并不能保证重试的事务将完成;可能需要多次重试。在竞争非常激烈的情况下,完成交易可能需要多次尝试。涉及冲突的已准备事务时,在已准备事务提交或回滚之前可能无法取得进展。