可重复读和可序列化隔离级别都可能产生旨在防止序列化异常的错误。如前所述,使用这些级别的应用程序必须准备好重试因序列化错误而失败的事务。这种错误的错误消息文本会根据具体情况而有所不同,但它始终具有 SQLSTATE 代码 40001
(serialization_failure
)。
重试死锁失败也可能是明智的。这些错误的 SQLSTATE 代码为 40P01
(deadlock_detected
)。
在某些情况下,重试唯一键失败(SQLSTATE 代码为 23505
(unique_violation
))和排除约束失败(SQLSTATE 代码为 23P01
(exclusion_violation
))也是合适的。例如,如果应用程序在检查当前存储的键后为主键列选择新值,则可能会因为另一个应用程序实例同时选择了相同的新键而导致唯一键失败。这实际上是序列化失败,但服务器不会将其检测为序列化失败,因为它无法“看到”插入值和之前的读取之间的连接。在某些特殊情况下,即使原则上服务器有足够的信息来确定序列化问题是根本原因,它也会发出唯一键或排除约束错误。虽然建议无条件地重试 serialization_failure
错误,但在重试这些其他错误代码时需要更加小心,因为它们可能表示持久性错误情况,而不是瞬时故障。
重要的是重试完整的事务,包括决定要发出哪些 SQL 和/或使用哪些值的所有逻辑。因此,PostgreSQL 不提供自动重试机制,因为它无法保证其正确性。
事务重试并不能保证重试的事务会完成;可能需要多次重试。在竞争非常激烈的情况下,可能需要多次尝试才能完成事务。如果涉及冲突的预备事务,则在预备事务提交或回滚之前,可能无法取得进展。
如果您在文档中发现任何不正确、与您使用特定功能的经验不符或需要进一步澄清的内容,请使用此表单来报告文档问题。