Mam dla Ciebie praktyczne rozwiązanie, które widziałem w projekcie w swoim miejscu pracy. Zamiast używać tylko 0 i 1 dla niekompletnych i wypełnionych, rozszerz swój zestaw, aby zawierał więcej przypadków.
Nazwijmy tę kolumnę stanem . Oto różne wartości tej kolumny i odpowiadające im stany zadania.
- Gdy status wynosi 0, zadanie nie zostało odebrane przez żaden wątek roboczy.
- Gdy status wynosi 1, zadanie zostało odebrane przez wątek roboczy i jest w trakcie przetwarzania.
- Gdy status wynosi 2, zadanie nie powiodło się. (Powinieneś rozważyć możliwość niepowodzenia przetwarzania.)
- Gdy status wynosi 3, zadanie zostało ukończone.
Twoje wątki powinny zawierać logikę w taki sposób, aby pobierała tylko zadania, których status wynosi 0 i zmieniała status na 1. To uniemożliwi innym wątkom pobieranie tych zadań, które są w trakcie przetwarzania. Po zakończeniu zadania status jest ustawiany na 3, a jeśli zadanie się nie powiedzie, status jest ustawiany na 2. Następnie wątek może przejść dalej i poszukać innego zadania, które nie zostało jeszcze ukończone.
Możesz również poprosić wątki o rozważenie wybrania zadań o statusie 2, ale będziesz musiał zdefiniować logikę, aby określić skończoną liczbę ponownych prób.
EDYTUJ:
Po długiej dyskusji , wspólnie natknęliśmy się na rozwiązanie. Moja powyższa odpowiedź jest dobra w bardziej uogólnionym stanie, gdy „praca” jest procesem, który zajmuje trochę czasu. Ale tak nie było w przypadku PO.
Rozwiązanie, które ostatecznie zadziałało, było następujące:
BEGIN
SELECT * FROM Jobs WHERE JobID = (SELECT * FROM Jobs WHERE completed = 0 LIMIT 1) LOCK IN SHARE MODE;
UPDATE Jobs SET completed = 1 WHERE JobID = (PREVIOUS ID);
COMMIT;