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