diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml index 341fea524a..6b02590971 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 INSERT - , the UPDATE clause will affect that row, + transaction whose effects are not yet visible to the INSERT, + the UPDATE clause will affect that row, even though possibly no version of that row is conventionally visible to the command. @@ -373,6 +373,37 @@ the case in Read Committed mode. + + MERGE allows the user to specify various + combinations of INSERT, UPDATE + and DELETE subcommands. A MERGE + command with both INSERT and UPDATE + subcommands looks similar to INSERT with an + ON CONFLICT DO UPDATE clause but does not + guarantee that either INSERT or + UPDATE will occur. + If MERGE attempts an UPDATE or + DELETE and the row is concurrently updated but + the join condition still passes for the current target and the + current source tuple, then MERGE will behave + the same as the UPDATE or + DELETE commands and perform its action on the + updated version of the row. However, because MERGE + 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 MERGE will + evaluate the condition's NOT MATCHED actions next, + and execute the first one that succeeds. + If MERGE attempts an INSERT + and a unique index is present and a duplicate row is concurrently + inserted, then a uniqueness violation error is raised; + MERGE does not attempt to avoid such + errors by evaluating MATCHED conditions. + + 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; 11, which no longer matches the criteria. - - MERGE allows the user to specify various - combinations of INSERT, UPDATE - or DELETE subcommands. A MERGE - command with both INSERT and UPDATE - subcommands looks similar to INSERT with an - ON CONFLICT DO UPDATE clause but does not - guarantee that either INSERT or - UPDATE will occur. - If MERGE attempts an UPDATE or - DELETE and the row is concurrently updated but - the join condition still passes for the current target and the - current source tuple, then MERGE will behave - the same as the UPDATE or - DELETE commands and perform its action on the - updated version of the row. However, because MERGE - 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 MERGE will - evaluate the condition's NOT MATCHED actions next, - and execute the first one that succeeds. - If MERGE attempts an INSERT - and a unique index is present and a duplicate row is concurrently - inserted, then a uniqueness violation is raised. - MERGE does not attempt to avoid the - error by executing an UPDATE. - - 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; - UPDATE, DELETE, SELECT - FOR UPDATE, and SELECT FOR SHARE commands + UPDATE, DELETE, + MERGE, SELECT FOR UPDATE, + and SELECT FOR SHARE commands behave the same as SELECT 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 f68aa09736..f0745d01c7 100644 --- a/doc/src/sgml/ref/merge.sgml +++ b/doc/src/sgml/ref/merge.sgml @@ -539,6 +539,10 @@ MERGE total_count + When MERGE is run concurrently with other commands + that modify the target table, the usual transaction isolation rules + apply; see for an explanation + on the behavior at each isolation level. You may also wish to consider using INSERT ... ON CONFLICT as an alternative statement which offers the ability to run an UPDATE if a concurrent INSERT