मेरे पास आपके लिए एक व्यावहारिक समाधान है, जिसे मैंने अपने कार्यस्थल पर एक परियोजना में कार्यान्वित होते देखा है। अपूर्ण और पूर्ण के लिए केवल 0 और 1 का उपयोग करने के बजाय, अधिक मामलों को शामिल करने के लिए अपने सेट का विस्तार करें।
चलिए उस कॉलम को स्थिति कहते हैं . यहां उस कॉलम के अलग-अलग मान और नौकरी की संबंधित स्थितियां दी गई हैं।
- जब स्थिति 0 होती है, तो किसी भी वर्कर थ्रेड द्वारा कार्य को नहीं लिया जाता है।
- जब स्थिति 1 होती है, तो कार्य को एक कार्यकर्ता सूत्र द्वारा उठा लिया जाता है और प्रक्रियाधीन होती है।
- जब स्थिति 2 होती है, तो कार्य विफल हो जाता है। (आपको प्रसंस्करण में विफलता की संभावना पर विचार करना चाहिए।)
- जब स्थिति 3 होती है, तो कार्य पूरा हो जाता है।
आपके थ्रेड्स में तर्क होना चाहिए जैसे कि यह केवल उन नौकरियों को उठाता है जिनके लिए स्थिति 0 है और स्थिति को 1 में बदल देती है। यह अन्य थ्रेड्स को उन नौकरियों को लेने की अनुमति नहीं देगा जो प्रक्रिया में हैं। जब कार्य पूरा हो जाता है, तो स्थिति 3 पर सेट हो जाती है और यदि कार्य विफल हो जाता है, तो स्थिति 2 पर सेट हो जाती है। फिर थ्रेड आगे बढ़ सकता है और किसी अन्य कार्य की तलाश कर सकता है जिसे अभी पूरा किया जाना है।
आप थ्रेड्स को स्थिति 2 की नौकरियों को चुनने पर विचार करने के लिए भी कह सकते हैं, लेकिन आपको सीमित संख्या में पुनर्प्रयासों को निर्दिष्ट करने के लिए तर्क को परिभाषित करना होगा।
संपादित करें:
लंबी चर्चा के बाद , हम एक साथ समाधान पर ठोकर खाई। मेरा उपरोक्त उत्तर अधिक सामान्यीकृत स्थिति में अच्छा है जब 'नौकरी' एक ऐसी प्रक्रिया है जिसे पूरा होने में कुछ समय लगता है। लेकिन ओपी की समस्या में ऐसा नहीं था।
तो जिस समाधान ने अंततः काम किया वह यह था:
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;