प्रति अनुरोध, यहां हमारी समस्या की रूपरेखा दी गई है, और हमने इसे कैसे हल किया:
हमारे सिस्टम में हमने एक कस्टम दस्तावेज़ लॉकिंग रूटीन (रेडिस-लॉक का उपयोग करके) बनाया, जिसमें इस सटीक (गलत) क्रम में निम्नलिखित हुआ:
संचालन का गलत क्रम:
- ग्राहक अनुरोध प्राप्त हुआ
- दस्तावेज़ लॉक किया गया
- दस्तावेज़ पुनर्प्राप्त
- दस्तावेज़ संपादित
- दस्तावेज़ अनलॉक किया गया
- ग्राहक अनुरोध का समाधान किया गया
- दस्तावेज़ सहेजा गया
एक बार जब आप इसे लिखा हुआ देखते हैं, तो समस्या स्पष्ट है:हम अपने दस्तावेज़ों को अपने दस्तावेज़ लॉक के बाहर सहेज रहे थे।
आइए मान लें कि #6 हमारे सिस्टम में 100ms लेता है। यह एक 100ms विंडो है जिसमें यदि कोई अन्य अनुरोध उसी दस्तावेज़ को पकड़ लेता है, तो हमारे पास एक सेव विरोध होगा (इस प्रश्न में शीर्षक त्रुटि मूल रूप से एक संघर्ष बचाओ IMHO है)।
दूसरे शब्दों/उदाहरण में:हमारे सिस्टम में, अनुरोध ए ने दस्तावेज़ एक्स के संस्करण 1 को पकड़ लिया, इसे संपादित किया, फिर इसे अनलॉक किया, लेकिन अनुरोध ए ने दस्तावेज़ को सहेजने से पहले, अनुरोध बी ने दस्तावेज़ एक्स को पकड़ लिया और इसे संस्करण 2 में बढ़ा दिया (मोंगो पर पढ़ें) इसके बारे में अधिक जानकारी के लिए संस्करण)। फिर अनुरोध ए अपने क्लाइंट अनुरोध को हल करता है और दस्तावेज़ एक्स को सहेजने के लिए जाता है, लेकिन यह संस्करण 1 को सहेजने का प्रयास कर रहा है, और अब यह देखता है कि इसका संस्करण 2 है, और इस प्रकार उपरोक्त त्रुटि है।
तो फिक्स आसान है। अपने दस्तावेज़ों को अपने लॉक के अंदर सहेजें। (उपरोक्त उदाहरण में, #7 को #5 से पहले ले जाएं। नीचे देखें।)
संचालन का सही/निश्चित क्रम
- ग्राहक अनुरोध प्राप्त हुआ
- दस्तावेज़ लॉक किया गया
- दस्तावेज़ पुनर्प्राप्त
- दस्तावेज़ संपादित
- दस्तावेज़ सहेजा गया
- दस्तावेज़ अनलॉक किया गया
- ग्राहक अनुरोध का समाधान किया गया
(आप तर्क दे सकते हैं कि #6 और #7 की अदला-बदली की जानी चाहिए, लेकिन यह Mongo/Mongoose/इस प्रश्न के दायरे से बाहर है।)
मैं थोड़ी देर के लिए इस प्रश्न को अनुत्तरित छोड़ने जा रहा हूं और देख सकता हूं कि प्रासंगिक कोड को अलग करने और इस समस्या का निवारण करने के लिए कोई बेहतर तरीके से कुछ प्रकाश डाल सकता है या नहीं। हमारे मामले में, यह एक बहुत ही व्यवस्थित समस्या थी और उस समय हमारे कौशल स्तर के लिए समस्या निवारण करना बहुत चुनौतीपूर्ण था।