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:
parent
e27f4ee0a7
commit
0adb3dc68b
@ -588,7 +588,7 @@ ERROR: could not serialize access due to concurrent update
|
|||||||
applications using this level must
|
applications using this level must
|
||||||
be prepared to retry transactions due to serialization failures.
|
be prepared to retry transactions due to serialization failures.
|
||||||
In fact, this isolation level works exactly the same as Repeatable
|
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
|
execution of a concurrent set of serializable transactions behave
|
||||||
in a manner inconsistent with all possible serial (one at a time)
|
in a manner inconsistent with all possible serial (one at a time)
|
||||||
executions of those transactions. This monitoring does not
|
executions of those transactions. This monitoring does not
|
||||||
@ -1720,6 +1720,72 @@ SELECT pg_advisory_lock(q.id) FROM
|
|||||||
</sect2>
|
</sect2>
|
||||||
</sect1>
|
</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">
|
<sect1 id="mvcc-caveats">
|
||||||
<title>Caveats</title>
|
<title>Caveats</title>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user