UPDATE
sperrt die Zeile, sodass Sie sie nicht zuerst sperren müssen. Wenn Sie versuchen, UPDATE
überlappende Sätze von Zeilen gleichzeitig, das zweite UPDATE
wartet darauf, dass die erste Transaktion festgeschrieben oder rückgängig gemacht wird.
Das große Problem bei Ihrem Ansatz - abgesehen davon, dass UPDATE
hat kein LIMIT
Klausel - ist, dass mehrere Arbeiter alle versuchen werden, die gleichen Zeilen zu greifen. Folgendes passiert:
- worker1:Filtert die Tabelle, um 200 Zeilen zu finden, und sperrt sie
- worker1:beginnt mit dem Aktualisieren von Zeilen
- worker2:filtert die Tabelle, um 200 Zeilen zu finden
- worker2:versucht, Zeilen zu aktualisieren, hat aber dieselben Zeilen wie worker1 ausgewählt, sodass es die Sperre von worker1 blockiert
- worker1:Beendet die Zeilenaktualisierung
- Arbeiter2:Prüft nach Freigabe der Sperre erneut die WHERE-Bedingung und stellt fest, dass keine der Zeilen mehr übereinstimmt, da Arbeitskraft1 sie aktualisiert hat. Aktualisiert null Zeilen.
... und wiederhole!
Sie müssen entweder:
- Haben Sie eine zentrale Warteschlange Verteilen von Zeilen auf eine ordnungsgemäße parallelitätssichere Weise; oder
- Weisen Sie Arbeitern sich nicht überschneidende ID-Bereiche zu, an denen sie arbeiten können
Wie bei LIMIT
- Sie könnten WHERE id IN (SELECT t.id FROM thetable t LIMIT 200 ORDER BY id)
verwenden - aber Sie hätten das gleiche Problem, wenn beide Worker denselben Satz von Zeilen zum Aktualisieren auswählen würden.