UPDATE
blokuje rząd, więc nie trzeba go najpierw blokować. Jeśli spróbujesz UPDATE
nakładające się zestawy wierszy jednocześnie, druga UPDATE
będzie czekać na zatwierdzenie lub wycofanie pierwszej transakcji.
Duży problem z twoim podejściem - inny niż fakt, że UPDATE
nie ma LIMIT
klauzula — wielu pracowników będzie próbowało pobrać te same wiersze. Oto, co się dzieje:
- pracownik1:Filtruje tabelę, aby znaleźć 200 wierszy i je blokuje
- pracownik1:rozpoczyna aktualizację wierszy
- worker2:filtruje tabelę, aby znaleźć 200 wierszy
- pracownik2:próbuje rozpocząć aktualizację wierszy, ale wybrał te same wiersze co pracownik1, więc blokuje się na blokadzie pracownika1
- pracownik1:Kończy aktualizowanie wierszy
- worker2:Po zwolnieniu blokady ponownie sprawdza warunek WHERE i dowiaduje się, że żaden z wierszy już nie pasuje, ponieważ pracownik 1 zaktualizował je. Aktualizuje zero wierszy.
... i powtórz!
Musisz:
- Miej centralną kolejkę rozdawanie wierszy w sposób bezpieczny dla współbieżności; lub
- Przypisz do pracowników nienakładające się zakresy identyfikatorów
Jak dla LIMIT
- można użyć WHERE id IN (SELECT t.id FROM thetable t LIMIT 200 ORDER BY id)
- ale masz ten sam problem, gdy obaj pracownicy wybierają ten sam zestaw wierszy do aktualizacji.