insert on conflict If not exist | INSERT INTO table1 (id) SELECT 1 WHERE NOT EXISTS ( SELECT 1 FROM table1 WHERE id = 1 -- for share ) ON CONFLICT DO NOTHING | Избыточная генерация PK. | Конструкция ON CONFLICT не защищает от обращения к генератору ключа (sequence). И это может привести к тому, что счетчик будет крутиться впустую. Использование выборки с условием вроде не убирает полностью ложные срабатывания (если они проходя одновременно), но после вставки записи, обращения к генератору прекратятся. PostgreSQL Antipatterns: накручиваем себе проблемы https://habr.com/ru/companies/tensor/articles/507688/ | | Postgres: INSERT if does not exist already https://stackoverflow.com/questions/4069718/postgres-insert-if-does-not-exist-already | Взаимодействие с блокировками | Поведение параллельных транзакций (Read Commited):Параллельные транзакции | select for update | update или delete | Без where exists | Не блокируется. | Блокируется. | С where exsists | Не блокируется | Не блокируется | с where exsists и for share | Блокируется | Блокируется. |
Важно подчеркнуть, select for update не всегда блокирует insert on conflict do nothing (как показано в таблице). В некоторых случаях может потребоваться явное ручное обновление записи для блокировки, чтобы заблокировать параллельные вызовы upsert (чтобы они они дождались завершения текущей транзакции), причем в том числе возможно перед проверкой условий. |
|