sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL-deadlocks vermijden bij het uitvoeren van bulkupdate- en verwijderingsbewerkingen

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.




  1. Wijzigingsmelding Oracle Database

  2. Hoe SQL Server op Linux te installeren

  3. PostgreSQL:zes niet-zo-gemakkelijke stukjes

  4. SQL Server - vind het nde voorkomen in een string