aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/mvcc.sgml71
-rw-r--r--doc/src/sgml/ref/merge.sgml4
2 files changed, 40 insertions, 35 deletions
diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml
index 341fea524a1..6b025909714 100644
--- a/doc/src/sgml/mvcc.sgml
+++ b/doc/src/sgml/mvcc.sgml
@@ -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>
@@ -374,6 +374,37 @@
</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
commands on the same rows it is trying to update, but it
@@ -423,37 +454,6 @@ COMMIT;
</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,
subsequent commands in the same transaction will see the effects
@@ -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
diff --git a/doc/src/sgml/ref/merge.sgml b/doc/src/sgml/ref/merge.sgml
index f68aa09736c..f0745d01c7d 100644
--- a/doc/src/sgml/ref/merge.sgml
+++ b/doc/src/sgml/ref/merge.sgml
@@ -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>