हालांकि यह सबसे अच्छा समाधान नहीं है, क्योंकि लॉक पंक्तियों को अनदेखा करने के लिए मुझे कोई रास्ता नहीं है, मैं एक यादृच्छिक एक चुनता हूं और लॉक प्राप्त करने का प्रयास करता हूं।
START TRANSACTION;
SET @v1 =(SELECT myId FROM tests.table WHERE status is NULL LIMIT 1);
SELECT * FROM tests.table WHERE [email protected] FOR UPDATE; #<- lock
, लेन-देन के लिए एक छोटे से समय-समाप्ति सेट करता है, तो उस पंक्ति के लॉक होने पर लेन-देन निरस्त किया गया है और मैं एक और कोशिश। अगर मैं ताला प्राप्त करता हूं, तो मैं इसे संसाधित करता हूं। अगर (दुर्भाग्य) उस पंक्ति को बंद कर दिया गया था, तो यह संसाधित हो जाता है और लॉक को मेरे टाइमआउट से पहले रिलीज़ किया जाता है, फिर मैं एक पंक्ति का चयन करता हूं जो पहले से ही 'संसाधित' हो चुका है! हालांकि, मैं एक ऐसी फ़ील्ड की जांच करता हूं जो मेरी प्रक्रियाओं को सेट करता है (उदा। स्थिति): यदि अन्य प्रक्रिया लेनदेन ठीक हो गया है, तो वह फ़ील्ड मुझे बताता है कि काम पहले से ही किया जा चुका है और मैं उस पंक्ति को दोबारा संसाधित नहीं करता हूं।
लेनदेन के बिना हर संभव संभावित समाधान (उदाहरण के लिए पंक्ति में कोई स्थिति नहीं है और ... आदि) आसानी से दौड़ की स्थिति और मिस्ड प्रक्रियाएं प्रदान कर सकती है (उदाहरण के लिए एक थ्रेड अचानक मर जाता है, आवंटित डेटा अभी भी टैग किया जाता है, जबकि एक सौदे की समय सीमा समाप्त;। रेफरी,, टिप्पणी here
आशा है कि यह
स्रोत
2017-07-06 09:34:42
+1 में मदद करता है आप LIMIT एक अच्छा विचार उपयोग कर रहा है –
इस उदाहरण में स्क्रिप्ट अचानक पहले अपडेट के बाद निरस्त किया गया है, तो कैसे होगा आप "क्लीन"। पुरानी प्रक्रियाओं से डेटाबेस? अन्यथा उन 100 पंक्तियों का कभी भी ख्याल नहीं रखा जाएगा। –
अच्छा सवाल। मैं आमतौर पर या तो एक ही कॉलम या ' राज्य के कॉलम को सफल समापन (लेनदेन के हिस्से के रूप में) इंगित करने के लिए। फिर यदि कोई प्रक्रिया मर जाती है, तो आप किसी अन्य प्रक्रिया के लिए गैर-मौजूदा प्रक्रिया के लिए किसी भी प्रक्रिया_आईडी को एनयूएलएल पर सेट कर सकते हैं। मैं सफाई के लिए क्रॉन नौकरियों को प्राथमिकता देता हूं, लेकिन आप इसे एक नई प्रक्रिया शुरू करने का भी हिस्सा बना सकते हैं। –