Link to MVCC docs in MERGE docs

In addition, this moves the new paragraph in the MVCC page upwards, for
a more consistent flow; some minor markup mistakes, style issues and
typos are fixed too.

Per comments from Justin Pryzby.

Discussion: https://postgr.es/m/20220511163350.GL19626@telsasoft.com
This commit is contained in:
Alvaro Herrera 2022-06-15 16:54:38 +02:00
parent a059e15cde
commit ffffeebf24
No known key found for this signature in database
GPG Key ID: 1C20ACB9D5C564AE
2 changed files with 40 additions and 35 deletions

View File

@ -359,8 +359,8 @@
behaves similarly. In Read Committed mode, each row proposed for insertion
will either insert or update. Unless there are unrelated errors, one of
those two outcomes is guaranteed. If a conflict originates in another
transaction whose effects are not yet visible to the <command>INSERT
</command>, the <command>UPDATE</command> clause will affect that row,
transaction whose effects are not yet visible to the <command>INSERT</command>,
the <command>UPDATE</command> clause will affect that row,
even though possibly <emphasis>no</emphasis> version of that row is
conventionally visible to the command.
</para>
@ -373,6 +373,37 @@
the case in Read Committed mode.
</para>
<para>
<command>MERGE</command> allows the user to specify various
combinations of <command>INSERT</command>, <command>UPDATE</command>
and <command>DELETE</command> subcommands. A <command>MERGE</command>
command with both <command>INSERT</command> and <command>UPDATE</command>
subcommands looks similar to <command>INSERT</command> with an
<literal>ON CONFLICT DO UPDATE</literal> clause but does not
guarantee that either <command>INSERT</command> or
<command>UPDATE</command> will occur.
If <command>MERGE</command> attempts an <command>UPDATE</command> or
<command>DELETE</command> and the row is concurrently updated but
the join condition still passes for the current target and the
current source tuple, then <command>MERGE</command> will behave
the same as the <command>UPDATE</command> or
<command>DELETE</command> commands and perform its action on the
updated version of the row. However, because <command>MERGE</command>
can specify several actions and they can be conditional, the
conditions for each action are re-evaluated on the updated version of
the row, starting from the first action, even if the action that had
originally matched appears later in the list of actions.
On the other hand, if the row is concurrently updated or deleted so
that the join condition fails, then <command>MERGE</command> will
evaluate the condition's <literal>NOT MATCHED</literal> actions next,
and execute the first one that succeeds.
If <command>MERGE</command> attempts an <command>INSERT</command>
and a unique index is present and a duplicate row is concurrently
inserted, then a uniqueness violation error is raised;
<command>MERGE</command> does not attempt to avoid such
errors by evaluating <literal>MATCHED</literal> conditions.
</para>
<para>
Because of the above rules, it is possible for an updating command to see
an inconsistent snapshot: it can see the effects of concurrent updating
@ -422,37 +453,6 @@ COMMIT;
<literal>11</literal>, which no longer matches the criteria.
</para>
<para>
<command>MERGE</command> allows the user to specify various
combinations of <command>INSERT</command>, <command>UPDATE</command>
or <command>DELETE</command> subcommands. A <command>MERGE</command>
command with both <command>INSERT</command> and <command>UPDATE</command>
subcommands looks similar to <command>INSERT</command> with an
<literal>ON CONFLICT DO UPDATE</literal> clause but does not
guarantee that either <command>INSERT</command> or
<command>UPDATE</command> will occur.
If MERGE attempts an <command>UPDATE</command> or
<command>DELETE</command> and the row is concurrently updated but
the join condition still passes for the current target and the
current source tuple, then <command>MERGE</command> will behave
the same as the <command>UPDATE</command> or
<command>DELETE</command> commands and perform its action on the
updated version of the row. However, because <command>MERGE</command>
can specify several actions and they can be conditional, the
conditions for each action are re-evaluated on the updated version of
the row, starting from the first action, even if the action that had
originally matched appears later in the list of actions.
On the other hand, if the row is concurrently updated or deleted so
that the join condition fails, then <command>MERGE</command> will
evaluate the condition's <literal>NOT MATCHED</literal> actions next,
and execute the first one that succeeds.
If <command>MERGE</command> attempts an <command>INSERT</command>
and a unique index is present and a duplicate row is concurrently
inserted, then a uniqueness violation is raised.
<command>MERGE</command> does not attempt to avoid the
error by executing an <command>UPDATE</command>.
</para>
<para>
Because Read Committed mode starts each command with a new snapshot
that includes all transactions committed up to that instant,
@ -516,8 +516,9 @@ COMMIT;
</para>
<para>
<command>UPDATE</command>, <command>DELETE</command>, <command>SELECT
FOR UPDATE</command>, and <command>SELECT FOR SHARE</command> commands
<command>UPDATE</command>, <command>DELETE</command>,
<command>MERGE</command>, <command>SELECT FOR UPDATE</command>,
and <command>SELECT FOR SHARE</command> commands
behave the same as <command>SELECT</command>
in terms of searching for target rows: they will only find target rows
that were committed as of the transaction start time. However, such a

View File

@ -539,6 +539,10 @@ MERGE <replaceable class="parameter">total_count</replaceable>
</para>
<para>
When <command>MERGE</command> is run concurrently with other commands
that modify the target table, the usual transaction isolation rules
apply; see <xref linkend="transaction-iso"/> for an explanation
on the behavior at each isolation level.
You may also wish to consider using <command>INSERT ... ON CONFLICT</command>
as an alternative statement which offers the ability to run an
<command>UPDATE</command> if a concurrent <command>INSERT</command>