sql >> Database >  >> RDS >> PostgreSQL

Hebben in PostgreSQL meerdere UPDATE's naar verschillende rijen in dezelfde tabel een conflicterende vergrendeling?

UPDATE vergrendelt de rij, zodat u deze niet eerst hoeft te vergrendelen. Als u probeert te UPDATE overlappende sets rijen tegelijk, de tweede UPDATE zal wachten tot de eerste transactie wordt vastgelegd of teruggedraaid.

Het grote probleem met uw aanpak - behalve het feit dat UPDATE heeft geen LIMIT clausule - is dat meerdere werkers allemaal dezelfde rijen proberen te pakken. Dit is wat er gebeurt:

  • werker1:filtert de tabel om 200 rijen te vinden en vergrendelt ze
  • werker1:begint rijen bij te werken
  • werker2:filtert de tabel om 200 rijen te vinden
  • worker2:probeert de rijen bij te werken, maar heeft dezelfde rijen als worker1 geselecteerd, dus het blokkeert op het slot van worker1
  • werker1:voltooit het bijwerken van rijen
  • worker2:controleert na het ontgrendelen van de vergrendeling de WHERE-voorwaarde opnieuw en ontdekt dat geen van de rijen meer overeenkomt omdat worker1 ze heeft bijgewerkt. Werkt nul rijen bij.

... en herhaal!

U moet ofwel:

  • Houd een centrale wachtrij het uitdelen van rijen op een goede gelijktijdigheidsveilige manier; of
  • Wijs werknemers niet-overlappende reeksen ID's toe om aan te werken

Wat betreft LIMIT - je zou kunnen gebruiken WHERE id IN (SELECT t.id FROM thetable t LIMIT 200 ORDER BY id) - maar u zou hetzelfde probleem hebben als beide werkers dezelfde reeks rijen kiezen om bij te werken.



  1. Selecteer onderscheiden op blob

  2. Hoeveel database-indexen is te veel?

  3. Gebruik een Postgres-trigger om de JSON van alleen de gewijzigde velden vast te leggen

  4. Query om alleen getallen uit een string te krijgen