Mám pro vás praktické řešení, které jsem viděl implementovat v projektu na svém pracovišti. Namísto použití pouze 0 a 1 pro neúplné a dokončené rozšiřte svou sadu tak, aby zahrnovala více případů.
Nazvěme tento sloupec stav . Zde jsou různé hodnoty tohoto sloupce a odpovídající stavy úlohy.
- Když je stav 0, úloha nebyla vyzvednuta žádným pracovním vláknem.
- Když je stav 1, úloha byla vyzvednuta pracovním vláknem a zpracovává se.
- Když je stav 2, úloha se nezdařila. (Měli byste zvážit možnost selhání při zpracování.)
- Když je stav 3, úloha byla dokončena.
Vaše vlákna by měla obsahovat takovou logiku, že vybírá pouze úlohy, u kterých je stav 0, a mění stav na 1. To znemožní ostatním vláknům vyzvednout úlohy, které se zpracovávají. Po dokončení úlohy se stav nastaví na 3 a pokud se úloha nezdaří, nastaví se stav na 2. Vlákno se pak může přesunout dál a hledat další úlohu, která má být ještě dokončena.
Můžete také požádat vlákna, aby zvážila vyzvednutí úloh se stavem 2, ale budete muset definovat logiku, abyste určili konečný počet opakování.
UPRAVIT:
Po dlouhé diskusi , společně jsme narazili na řešení. Moje výše uvedená odpověď je dobrá v obecnějším stavu, kdy je „úkol“ proces, jehož dokončení nějakou dobu trvá. Ale to nebyl případ problému OP.
Takže řešení, které nakonec fungovalo, bylo toto:
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;