Both Repeatable Read and Serializable isolation levels can produce
errors that are designed to prevent serialization anomalies. As
previously stated, applications using these levels must be prepared to
retry transactions that fail due to serialization errors. Such an
error's message text will vary according to the precise circumstances,
but it will always have the SQLSTATE code <literal>40001</literal>
(<literal>serialization_failure</literal>).
リピータブルリード分離レベルとシリアライザブル分離レベルはどちらも、直列化異常を防止するように設計されたエラーを生成する可能性があります。
前述のように、これらのレベルを使用するアプリケーションは、直列化エラーが原因で失敗したトランザクションを再試行するように準備する必要があります。
このようなエラーのメッセージ・テキストは細かい状況によって異なりますが、常にSQLSTATEコードは40001
(serialization_failure
)となります。
It may also be advisable to retry deadlock failures.
These have the SQLSTATE code <literal>40P01</literal>
(<literal>deadlock_detected</literal>).
SQLSTATEコード40P01
(deadlock_detected
)を持つデッドロック障害を再試行することも推奨されます。
In some cases it is also appropriate to retry unique-key failures,
which have SQLSTATE code <literal>23505</literal>
(<literal>unique_violation</literal>), and exclusion constraint
failures, which have SQLSTATE code <literal>23P01</literal>
(<literal>exclusion_violation</literal>). For example, if the
application selects a new value for a primary key column after
inspecting the currently stored keys, it could get a unique-key
failure because another application instance selected the same new key
concurrently. This is effectively a serialization failure, but the
server will not detect it as such because it cannot <quote>see</quote>
the connection between the inserted value and the previous reads.
There are also some corner cases in which the server will issue a
unique-key or exclusion constraint error even though in principle it
has enough information to determine that a serialization problem
is the underlying cause. While it's recommendable to just
retry <literal>serialization_failure</literal> errors unconditionally,
more care is needed when retrying these other error codes, since they
might represent persistent error conditions rather than transient
failures.
場合によっては、SQLSTATEコード23505
(unique_violation
)を持つ一意キーの失敗、およびSQLSTATEコード23P01
(exclusion_violation
)を持つ排他制約の失敗を再試行することも適切です。
たとえば、現在格納されているキーを検査した後にアプリケーションが主キー列に新しい値を選択した場合、別のアプリケーション・インスタンスが同じ新しいキーを同時に選択したため、一意キーの失敗が発生する可能性があります。
これは実質的に直列化の失敗ですが、サーバは挿入された値と前の読み取りとの間の関係を「参照」できないため、直列化の失敗を検出しません。
また、原則として直列化の問題が根本原因であると判断するのに十分な情報があるにもかかわらず、サーバが一意キーまたは排他制約のエラーを発行する場合もあります。
serialization_failure
エラーを無条件に再試行することをお薦めしますが、これらの他のエラー・コードを再試行する場合は、一時的な失敗ではなく永続的なエラー条件を表す可能性があるため、より注意が必要です。
It is important to retry the complete transaction, including all logic that decides which SQL to issue and/or which values to use. Therefore, <productname>PostgreSQL</productname> does not offer an automatic retry facility, since it cannot do so with any guarantee of correctness. どのSQLを発行するか、どの値を使用するかを決定するすべてのロジックを含む完全なトランザクションを再試行することが重要です。 したがって、PostgreSQLは自動再試行機能を提供していません。 なぜなら、自動再試行機能は正当性を保証できないからです。
Transaction retry does not guarantee that the retried transaction will complete; multiple retries may be needed. In cases with very high contention, it is possible that completion of a transaction may take many attempts. In cases involving a conflicting prepared transaction, it may not be possible to make progress until the prepared transaction commits or rolls back. トランザクションの再試行は、再試行されたトランザクションが完了することを保証するものではありません。 複数回の再試行が必要になる場合があります。 競合が非常に高い場合は、トランザクションの完了に多くの試行が必要になる可能性があります。 競合する準備済トランザクションが関係する場合は、準備済トランザクションがコミットまたはロールバックされるまで進行できない可能性があります。