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.