Исходный код вики Insert or update. Upsert

Редактировал(а) Alexandr Fokin 2025/06/22 17:41

Последние авторы
1 (% style="width:1456px" %)
2 |(% style="width:139px" %) |(% style="width:264px" %) |(% style="width:1079px" %)
3 |(% style="width:139px" %)insert on conflict
4 If not exist|(% style="width:264px" %){{code language="sql"}}INSERT INTO table1
5 (id)
6 SELECT 1
7 WHERE
8 NOT EXISTS (
9 SELECT 1
10 FROM table1
11 WHERE id = 1
12 -- for share
13 )
14 ON CONFLICT DO NOTHING{{/code}}|(% style="width:1079px" %)(((
15 |(% style="width:115px" %)Избыточная генерация PK.|(% style="width:924px" %)(((
16 Конструкция {{code language="sql"}}ON CONFLICT{{/code}} не защищает от обращения к генератору ключа (sequence). И это может привести к тому, что счетчик будет крутиться впустую.
17 Использование выборки с условием вроде не убирает полностью ложные срабатывания (если они проходя одновременно), но после вставки записи, обращения к генератору прекратятся.
18
19 PostgreSQL Antipatterns: накручиваем себе проблемы
20 [[https:~~/~~/habr.com/ru/companies/tensor/articles/507688/>>url:https://habr.com/ru/companies/tensor/articles/507688/]]
21 )))
22 |(% style="width:115px" %) |(% style="width:924px" %)Postgres: INSERT if does not exist already
23 [[https:~~/~~/stackoverflow.com/questions/4069718/postgres-insert-if-does-not-exist-already>>url:https://stackoverflow.com/questions/4069718/postgres-insert-if-does-not-exist-already]]
24 |(% style="width:115px" %)Взаимодействие с блокировками|(% style="width:924px" %)Поведение параллельных транзакций (Read Commited):(((
25 |(% style="width:248px" %)Параллельные транзакции|(% style="width:303px" %)select for update|(% style="width:348px" %)update или delete
26 |(% style="width:248px" %)Без where exists|(% style="width:303px" %)Не блокируется.|(% style="width:348px" %)Блокируется.
27 |(% style="width:248px" %)С where exsists|(% style="width:303px" %)Не блокируется|(% style="width:348px" %)Не блокируется
28 |(% style="width:248px" %)с where exsists и for share|(% style="width:303px" %)Блокируется|(% style="width:348px" %)Блокируется.
29
30 Важно подчеркнуть, {{code language="sql"}}select for update{{/code}} не всегда блокирует {{code language="sql"}}insert on conflict do nothing{{/code}} (как показано в таблице).
31 В некоторых случаях может потребоваться явное ручное обновление записи для блокировки, чтобы заблокировать параллельные вызовы upsert (чтобы они они дождались завершения текущей транзакции), причем в том числе возможно перед проверкой условий.
32 )))
33 )))
34 |(% style="width:139px" %)Merge|(% style="width:264px" %) |(% style="width:1079px" %)Не ждет блокировок.
35 |(% style="width:139px" %){{{WITH upsert}}}|(% style="width:264px" %) |(% style="width:1079px" %)
36
37 ----
38
39 ==== Внутренние ссылки: ====
40
41 ====== Дочерние страницы: ======
42
43 {{children/}}
44
45 ====== Обратные ссылки: ======
46
47 {{velocity}}
48 #set ($links = $doc.getBacklinks())
49 #if ($links.size() > 0)
50 #foreach ($docname in $links)
51 #set ($rdoc = $xwiki.getDocument($docname).getTranslatedDocument())
52 * [[$escapetool.xml($rdoc.fullName)]]
53 #end
54 #else
55 No back links for this page!
56 #end
57 {{/velocity}}
58
59 ----