Brug eksplicit låsning på rækkeniveau i ordnede underforespørgsler i alle konkurrerende forespørgsler .
(VÆLG konkurrerer ikke med skrivelåse.)
SLET
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;
OPDATERING
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;
På denne måde låses rækker i ensartet rækkefølge som anbefalet i manualen.
Forudsat at id_A
, id_B
bliver aldrig opdateret, selv sjældne komplikationer i hjørnet, som beskrevet i boksen "Forsigtig" i manualen, er ikke mulige.
Mens du ikke opdaterer nøglekolonner, kan du bruge den svagere låsetilstand FOR INGEN NØGLEOPDATERING
. Kræver Postgres 9.3 eller nyere.
Den anden (langsom og sikker) mulighed er at bruge det serialiserede isolationsniveau til konkurrerende transaktioner. Du skal forberede dig på serialiseringsfejl, i hvilket tilfælde du skal prøve kommandoen igen.