Gebruik expliciete vergrendeling op rijniveau in geordende subquery's in alle concurrerende zoekopdrachten .
(SELECT
concurreert niet met schrijfvergrendelingen.)
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;
Op deze manier worden rijen in een consistente volgorde vergrendeld, zoals geadviseerd in de handleiding.
Ervan uitgaande dat id_A
, id_B
worden nooit bijgewerkt, zelfs zeldzame complicaties in de hoek, zoals beschreven in het vak "Let op" in de handleiding, zijn niet mogelijk.
Terwijl u de sleutelkolommen niet bijwerkt, kunt u de zwakkere vergrendelingsmodus gebruiken FOR NO KEY UPDATE
. Vereist Postgres 9.3 of hoger.
De andere (traag en zeker) optie is om het serialiseerbare isolatieniveau te gebruiken voor concurrerende transacties. U zou zich moeten voorbereiden op serialisatiefouten, in welk geval u de opdracht opnieuw moet proberen.