1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-01 01:04:50 +03:00

Doc: add some documentation about serialization failure handling.

We weren't very explicit about when to retry such errors.

Simon Riggs

Discussion: https://postgr.es/m/CANbhV-E+u+Z4VBNyJ6GzeO1fd2wP_5S+f6+kmxnN+ALQE6iG9Q@mail.gmail.com
This commit is contained in:
Tom Lane 2022-03-24 13:34:27 -04:00
parent e27f4ee0a7
commit 0adb3dc68b

View File

@ -588,7 +588,7 @@ ERROR: could not serialize access due to concurrent update
applications using this level must
be prepared to retry transactions due to serialization failures.
In fact, this isolation level works exactly the same as Repeatable
Read except that it monitors for conditions which could make
Read except that it also monitors for conditions which could make
execution of a concurrent set of serializable transactions behave
in a manner inconsistent with all possible serial (one at a time)
executions of those transactions. This monitoring does not
@ -1720,6 +1720,72 @@ SELECT pg_advisory_lock(q.id) FROM
</sect2>
</sect1>
<sect1 id="mvcc-serialization-failure-handling">
<title>Serialization Failure Handling</title>
<indexterm>
<primary>serialization failure</primary>
</indexterm>
<indexterm>
<primary>retryable error</primary>
</indexterm>
<para>
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>).
</para>
<para>
It may also be advisable to retry deadlock failures.
These have the SQLSTATE code <literal>40P01</literal>
(<literal>deadlock_detected</literal>).
</para>
<para>
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.
</para>
<para>
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.
</para>
<para>
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.
</para>
</sect1>
<sect1 id="mvcc-caveats">
<title>Caveats</title>