PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Unikanie zakleszczeń PostgreSQL podczas wykonywania zbiorczych operacji aktualizacji i usuwania

Używaj jawnego blokowania na poziomie wiersza w uporządkowanych podzapytaniach we wszystkich konkurencyjnych zapytaniach .
(SELECT nie konkuruje z blokadami zapisu.)

DELETE

DELETE FROM table_name t
USING (
   SELECT id_A, id_B
   FROM   table_name 
   WHERE  id_A = ANY(array_of_id_A)
   AND    id_B = ANY(array_of_id_B)
   ORDER  BY id_A, id_B
   FOR    UPDATE
   ) del
WHERE  t.id_A = del.id_A
AND    t.id_B = del.id_B;

UPDATE

UPDATE table_name t
SET    val_1 = 'some value'
     , val_2 = 'some value'
FROM  (
   SELECT id_A, id_B
   FROM   table_name 
   WHERE  id_A = ANY(array_of_id_A)
   AND    id_B = ANY(array_of_id_B)
   ORDER  BY id_A, id_B
   FOR    NO KEY UPDATE  -- Postgres 9.3+
-- FOR    UPDATE         -- for older versions or updates on key columns
   ) upd
WHERE  t.id_A = upd.id_A
AND    t.id_B = upd.id_B;

W ten sposób wiersze są blokowane w spójnej kolejności, zgodnie z zaleceniami w instrukcji.

Zakładając, że id_A , id_B nigdy nie są aktualizowane, nawet rzadkie komplikacje przypadków narożnych, takie jak wyszczególnione w polu „Uwaga” w instrukcji, nie są możliwe.

Jeśli nie aktualizujesz kolumn kluczy, możesz użyć słabszego trybu blokady FOR NO KEY UPDATE . Wymaga Postgresa 9.3 lub nowszego.

Drugi (wolny i na pewno) jest opcja użycia serializowalnego poziomu izolacji dla transakcji konkurujących. Musiałbyś przygotować się na błędy serializacji, w którym to przypadku musisz ponowić polecenie.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Grupa użytkowników PostgreSQL NL

  2. Jak zabezpieczyć bazę danych PostgreSQL — 10 wskazówek

  3. Jak rozumieć ANALIZĘ WYJAŚNIJ

  4. Aktualizacja PostgreSQL 11 do PostgreSQL 13 z TimescaleDB i PostGIS w systemie Linux przy użyciu pg_upgrade

  5. Jak mogę zaimportować dane z ASCII (ISO/IEC 8859-1) do mojej bazy danych Rails/PGSQL?