MongoDB में लेनदेन की कमी के आसपास कैसे काम करें?


139

मुझे पता है कि यहां भी इसी तरह के सवाल हैं, लेकिन वे मुझे नियमित आरडीबीएमएस सिस्टम में वापस जाने के लिए कह रहे हैं, अगर मुझे लेनदेन की आवश्यकता है या परमाणु संचालन या दो-चरणीय प्रतिबद्ध का उपयोग करना है । दूसरा समाधान सबसे अच्छा विकल्प लगता है। तीसरा, मैं इसका पालन नहीं करना चाहता क्योंकि ऐसा लगता है कि कई चीजें गलत हो सकती हैं और मैं इसे हर सूरत में परख नहीं सकता। मुझे परमाणु परिचालनों को करने के लिए अपनी परियोजना को फिर से शुरू करने में मुश्किल समय आ रहा है। मुझे नहीं पता कि यह मेरे सीमित दृष्टिकोण से आता है (मैंने अब तक केवल SQL डेटाबेस के साथ काम किया है), या क्या यह वास्तव में नहीं किया जा सकता है।

हम अपनी कंपनी में MongoDB का परीक्षण करना चाहते हैं। हमने एक अपेक्षाकृत सरल प्रोजेक्ट चुना है - एक एसएमएस गेटवे। यह हमारे सॉफ़्टवेयर को सेलुलर नेटवर्क पर एसएमएस संदेश भेजने की अनुमति देता है और गेटवे गंदा काम करता है: वास्तव में प्रदाताओं के साथ विभिन्न संचार प्रोटोकॉल के माध्यम से संवाद करना। गेटवे संदेशों की बिलिंग को भी प्रबंधित करता है। सेवा के लिए आवेदन करने वाले प्रत्येक ग्राहक को कुछ क्रेडिट खरीदने होते हैं। जब संदेश भेजा जाता है और संतुलन अपर्याप्त होने पर अभिगमन को अस्वीकार कर देता है, तो सिस्टम स्वचालित रूप से उपयोगकर्ता के संतुलन को कम कर देता है। इसके अलावा, क्योंकि हम तीसरे पक्ष के एसएमएस प्रदाताओं के ग्राहक हैं, इसलिए हमारे पास उनके साथ हमारे अपने संतुलन भी हो सकते हैं। हमें उन पर भी नजर रखनी होगी।

मैंने यह सोचना शुरू कर दिया कि अगर मैं कुछ जटिलता (बाहरी बिलिंग, कतारबद्ध एसएमएस भेजने) में कटौती करता हूं तो मैं MongoDB के साथ आवश्यक डेटा कैसे संग्रहीत कर सकता हूं। SQL दुनिया से आते हुए, मैं उपयोगकर्ताओं के लिए एक अलग तालिका, एसएमएस संदेशों के लिए एक और एक, उपयोगकर्ताओं के शेष के बारे में लेनदेन के भंडारण के लिए एक बनाऊंगा। मान लीजिए कि मैं MongoDB में उन सभी के लिए अलग संग्रह बनाता हूं।

इस सरल प्रणाली में निम्नलिखित चरणों के साथ एक एसएमएस भेजने वाले कार्य की कल्पना करें:

  1. जांचें कि क्या उपयोगकर्ता के पास पर्याप्त संतुलन है; यदि पर्याप्त क्रेडिट नहीं है तो इनकार कर दें

  2. एसएमएस संग्रह में विवरण और लागत के साथ संदेश को भेजें और संग्रहीत करें (लाइव सिस्टम में संदेश में एक statusविशेषता होगी और एक कार्य इसे डिलीवरी के लिए उठाएगा और एसएमएस की कीमत अपनी वर्तमान स्थिति के अनुसार निर्धारित करेगा)

  3. भेजे गए संदेश की लागत से उपयोगकर्ताओं का संतुलन कम करना

  4. लेन-देन संग्रह में लेन-देन लॉग इन करें

अब इसमें क्या दिक्कत है? MongoDB परमाणु अद्यतन केवल एक दस्तावेज़ पर कर सकता है। पिछले प्रवाह में ऐसा हो सकता है कि डेटाबेस में किसी प्रकार की त्रुटि हो जाती है और संदेश संग्रहीत हो जाता है, लेकिन उपयोगकर्ता का संतुलन अपडेट नहीं होता है और / या लेन-देन लॉग नहीं होता है।

मैं दो विचारों के साथ आया:

  • उपयोगकर्ताओं के लिए एक एकल संग्रह बनाएं, और शेष राशि को उपयोगकर्ता के दस्तावेज़ में उप-दस्तावेज़ के रूप में एक क्षेत्र, उपयोगकर्ता से संबंधित लेनदेन और संदेशों के रूप में संग्रहीत करें। क्योंकि हम दस्तावेजों को परमाणु रूप से अपडेट कर सकते हैं, यह वास्तव में लेनदेन की समस्या को हल करता है। नुकसान: यदि उपयोगकर्ता कई एसएमएस संदेश भेजता है, तो दस्तावेज़ का आकार बड़ा हो सकता है और 4 एमबी दस्तावेज़ सीमा तक पहुंचा जा सकता है। शायद मैं ऐसे परिदृश्यों में इतिहास के दस्तावेज़ बना सकता हूं, लेकिन मुझे नहीं लगता कि यह एक अच्छा विचार होगा। इसके अलावा, मुझे नहीं पता कि अगर मैं एक ही बड़े दस्तावेज़ में अधिक से अधिक डेटा धक्का देता हूं तो सिस्टम कितना तेज होगा।

  • उपयोगकर्ताओं के लिए एक संग्रह बनाएं, और लेनदेन के लिए एक। दो प्रकार के लेन-देन हो सकते हैं: सकारात्मक शेष परिवर्तन के साथ ऋण खरीद और नकारात्मक शेष परिवर्तन के साथ भेजे गए संदेश । लेन-देन में एक उप-साक्षरता हो सकती है; उदाहरण के लिए भेजे गए संदेशों में एसएमएस का विवरण लेनदेन में एम्बेड किया जा सकता है। नुकसान: मैं वर्तमान उपयोगकर्ता शेष को संग्रहीत नहीं करता हूं इसलिए मुझे हर बार यह गणना करना होगा कि उपयोगकर्ता यह बताने के लिए संदेश भेजने की कोशिश करता है कि क्या संदेश के माध्यम से जा सकता है या नहीं। मुझे डर है कि यह गणना धीमी हो सकती है क्योंकि संग्रहीत लेनदेन की संख्या बढ़ती है।

मैं थोड़ा उलझन में हूं कि किस विधि को चुना जाए। क्या अन्य उपाय हैं? मैं इस तरह की समस्याओं के आसपास काम करने के बारे में ऑनलाइन कोई सर्वोत्तम अभ्यास नहीं खोज सका। मुझे लगता है कि कई प्रोग्रामर जो NoSQL दुनिया से परिचित होने की कोशिश कर रहे हैं, वे शुरुआत में इसी तरह की समस्याओं का सामना कर रहे हैं।


61
मुझे माफ कर दो अगर मैं गलत हूं, लेकिन ऐसा लगता है कि यह परियोजना एक NoSQL डेटा स्टोर का उपयोग करने जा रही है, चाहे वह इससे लाभान्वित हो या नहीं। NoSQL एसक्यूएल के लिए एक "फैशन" विकल्प के रूप में एक विकल्प नहीं हैं, लेकिन जब संबंधपरक आरडीबीएमएस की तकनीक समस्या स्थान पर फिट नहीं होती है और एक गैर-संबंधपरक डेटास्टोर करता है। आपके बहुत से प्रश्न में "यदि यह SQL था तो ..." और यह चेतावनी मेरे लिए घंटी बजाती है। सभी NoSQL की समस्या को हल करने की आवश्यकता से आए हैं जो SQL नहीं कर सकता है और फिर उनका उपयोग करने में आसान बनाने के लिए कुछ हद तक सामान्यीकृत किया गया है और फिर निश्चित रूप से बैंडवागन को रोल करना शुरू हो जाता है।
पर्पलिलॉट

4
मुझे पता है कि यह परियोजना NoSQL को आज़माने के लिए सबसे अच्छा नहीं है। हालाँकि, मुझे डर लगता है अगर हम इसे अन्य परियोजनाओं के साथ उपयोग करना शुरू करते हैं (चलो एक पुस्तकालय संग्रह प्रबंधन सॉफ्टवेयर कहते हैं क्योंकि हम संग्रह प्रबंधन में हैं) और अचानक किसी प्रकार का अनुरोध आता है जिसमें लेनदेन की आवश्यकता होती है (और यह वास्तव में वहां है, कल्पना करें कि एक किताबें एक संग्रह से दूसरे में स्थानांतरित किया जाता है) हमें यह जानना होगा कि हम समस्या को कैसे दूर कर सकते हैं। शायद यह सिर्फ मैं ही हूं जो संकीर्ण सोच वाला है और सोचता है कि लेन-देन की हमेशा जरूरत होती है। लेकिन यह किसी भी तरह से इन पर काबू पाने का एक तरीका हो सकता है।
नागी

3
मैं पर्पलिपॉट से सहमत हूं, आपको एक ऐसी तकनीक का चयन करना चाहिए जो एक समाधान के लिए उपयुक्त हो, एक ऐसे समाधान को तैयार करने की कोशिश न करें जो किसी समस्या पर उचित नहीं है। ग्राफ डेटाबेस के लिए मॉडलिंग डेटा RDBMS डिजाइन की तुलना में एक पूरी तरह से अलग प्रतिमान है और आपको अपने द्वारा जानी जाने वाली हर चीज को भूलना होगा और नए तरीके से सोचना चाहिए।

9
मैं समझता हूं कि मुझे कार्य के लिए उपयुक्त उपकरण का उपयोग करना चाहिए। हालाँकि मेरे लिए - जब मैं इस तरह से उत्तर पढ़ता हूँ - तो ऐसा लगता है कि NoSQL उन चीज़ों के लिए अच्छा नहीं है जहाँ डेटा महत्वपूर्ण है। यह फेसबुक या ट्विटर के लिए अच्छा है जहां अगर कुछ टिप्पणियां खो जाती हैं तो दुनिया चल जाती है, लेकिन इससे ऊपर कुछ भी व्यापार से बाहर है। अगर यह सच है, तो मुझे यह समझ में नहीं आता है कि अन्य की देखभाल जैसे भवन निर्माण के बारे में क्यों। MongoDB के साथ एक वेबस्टोर: kylebanker.com/blog/2010/04/30/mongodb-and-ecommerce यह भी उल्लेख है कि अधिकांश लेनदेन को परमाणु संचालन से दूर किया जा सकता है। मैं जो खोज रहा हूं वह कैसे है।
नागी

2
आप कहते हैं "ऐसा लगता है कि NoSQL कुछ भी जहाँ डेटा महत्वपूर्ण है के लिए अच्छा नहीं है" यह सच नहीं है जहाँ यह अच्छा नहीं है (हो सकता है) ट्रांजेक्शनल ACID टाइप ट्रांसेक्शनल प्रोसेसिंग हो। इसके अलावा NoSQL के वितरित डेटा स्टोर के लिए डिज़ाइन किए गए हैं जो कि जब आप मास्टर दास प्रतिकृति परिदृश्यों में प्राप्त करते हैं तो SQL प्रकार के स्टोर को प्राप्त करना बहुत मुश्किल हो सकता है। NoSQL में अंतिम स्थिरता के लिए रणनीति है और यह सुनिश्चित करता है कि केवल नवीनतम डेटा सेट का उपयोग किया जाए लेकिन ACID नहीं।
पर्पलिपॉट

जवाबों:


23

4.0 के रूप में, MongoDB में बहु-दस्तावेज़ ACID लेनदेन होंगे। योजना पहले प्रतिकृति सेट तैनाती में उन लोगों को सक्षम करने के लिए है, जिसके बाद शार्प कलस्टर हैं। MongoDB में लेन-देन महसूस होगा जैसे लेन-देन डेवलपर्स रिलेशनल डेटाबेस से परिचित हैं - वे बहु-कथन होंगे, समान शब्दार्थ और वाक्यविन्यास (जैसे start_transactionऔर commit_transaction)। महत्वपूर्ण रूप से, लेन-देन को सक्षम करने वाले MongoDB में परिवर्तन कार्यभार के लिए प्रदर्शन को प्रभावित नहीं करते हैं जिनकी उन्हें आवश्यकता नहीं है।

अधिक जानकारी के लिए यहां देखें ।

वितरित लेनदेन होने का मतलब यह नहीं है कि आपको अपना डेटा सारणीबद्ध संबंधपरक डेटाबेस की तरह बनाना चाहिए। दस्तावेज़ मॉडल की शक्ति को गले लगाओ और डेटा मॉडलिंग की अच्छी और अनुशंसित प्रथाओं का पालन ​​करें ।


1
लेन-देन आ गया! 4.0 GA'ed। mongodb.com/blog/post/…
ग्रिगोरी मेलनिक

MongoDB लेनदेन में अभी भी लेन-देन के आकार 16 MB तक सीमित है, हाल ही में मेरे पास एक उपयोग का मामला था जहां मुझे फ़ाइल से 50k रिकॉर्ड को mongoDB में डालने की आवश्यकता है, इसलिए परमाणु संपत्ति को बनाए रखने के लिए मैंने लेनदेन का उपयोग करने के बारे में सोचा लेकिन 50 के बाद से json रिकॉर्ड इस सीमा से अधिक होने पर, यह "सभी लेनदेन परिचालनों का कुल आकार 16793600 से कम होना चाहिए। वास्तविक आकार 16793817" है। अधिक जानकारी के लिए आप mongoDB jira.mongodb.org/browse/SERVER-36330
Gautam Malik

MongoDB 4.2 (वर्तमान में बीटा में, RC4) बड़े लेनदेन का समर्थन करता है। कई ओपलॉग प्रविष्टियों में लेनदेन का प्रतिनिधित्व करने से, आप 16MB से अधिक डेटा को एक एकल ACID लेनदेन (मौजूदा 60-सेकंड डिफ़ॉल्ट अधिकतम निष्पादन समय के अधीन) में लिख पाएंगे। आप उन्हें अभी आज़मा सकते हैं - mongodb.com/download-center/community
ग्रिगोरी मेलनिक

MongoDB 4.2 अब वितरित लेनदेन के पूर्ण समर्थन के साथ GA है। mongodb.com/blog/post/…
ग्रिगोरि मेलनिक

83

बिना लेन-देन के रहना

लेनदेन ACID संपत्तियों का समर्थन करते हैं, लेकिन हालांकि इसमें कोई लेन-देन नहीं है MongoDB, हमारे पास परमाणु संचालन हैं। ठीक है, परमाणु संचालन का मतलब है कि जब आप किसी एक दस्तावेज़ पर काम करते हैं तो उस काम को किसी अन्य दस्तावेज़ को देखने से पहले पूरा किया जाएगा। वे उन सभी परिवर्तनों को देखेंगे जो हमने किए थे या उनमें से कोई भी नहीं था। और परमाणु संचालन का उपयोग करते हुए, आप अक्सर एक ही चीज़ को पूरा कर सकते हैं जो हमने एक रिलेशनल डेटाबेस में लेनदेन का उपयोग करके पूरा किया होगा। और इसका कारण यह है कि, एक संबंधपरक डेटाबेस में, हमें कई तालिकाओं में परिवर्तन करने की आवश्यकता है। आमतौर पर तालिकाओं में शामिल होने की आवश्यकता होती है और इसलिए हम एक ही बार में ऐसा करना चाहते हैं। और ऐसा करने के लिए, चूंकि कई तालिकाएं हैं, इसलिए हमें एक लेनदेन शुरू करना होगा और उन सभी अपडेट को करना होगा और फिर लेनदेन को समाप्त करना होगा। लेकिन इसके साथMongoDB, हम डेटा को एम्बेड करने जा रहे हैं, क्योंकि हम इसे दस्तावेजों में पहले से शामिल करने जा रहे हैं और वे ये समृद्ध दस्तावेज़ हैं जिनमें पदानुक्रम है। हम अक्सर एक ही बात को पूरा कर सकते हैं। उदाहरण के लिए, ब्लॉग उदाहरण में, यदि हम यह सुनिश्चित करना चाहते हैं कि हमने एक ब्लॉग पोस्ट को परमाणु रूप से अपडेट किया है, तो हम ऐसा कर सकते हैं क्योंकि हम एक ही बार में पूरे ब्लॉग पोस्ट को अपडेट कर सकते हैं। जैसे कि यदि यह संबंधपरक तालिकाओं का एक गुच्छा था, तो हमें संभवतः एक लेनदेन खोलना होगा ताकि हम पोस्ट संग्रह और टिप्पणियों के संग्रह को अपडेट कर सकें।

तो हमारे दृष्टिकोण क्या हैं जो हम MongoDBलेनदेन की कमी को दूर करने के लिए ले सकते हैं ?

  • पुनर्गठन - कोड का पुनर्गठन, ताकि हम एक दस्तावेज़ के भीतर काम कर रहे हैं और उस दस्तावेज़ के भीतर पेश किए जाने वाले परमाणु संचालन का लाभ उठा रहे हैं। और अगर हम ऐसा करते हैं, तो आमतौर पर हम सभी सेट होते हैं।
  • सॉफ्टवेयर में कार्यान्वयन - हम एक महत्वपूर्ण अनुभाग बनाकर, सॉफ्टवेयर में लॉकिंग को लागू कर सकते हैं। हम खोज और संशोधन का उपयोग करके एक परीक्षण, परीक्षण और सेट का निर्माण कर सकते हैं। हम जरूरत पड़ने पर सेमाफोर का निर्माण कर सकते हैं। और एक तरह से, जिस तरह से बड़ी दुनिया वैसे भी काम करती है। अगर हम इसके बारे में सोचते हैं, अगर एक बैंक को दूसरे बैंक में पैसे ट्रांसफर करने की जरूरत होती है, तो वे एक ही रिलेशनल सिस्टम में नहीं रहते हैं। और वे अक्सर अपने स्वयं के संबंधपरक डेटाबेस होते हैं। और उन्हें उस ऑपरेशन को समन्वित करने में सक्षम होना चाहिए, भले ही हम उन डेटाबेस प्रणालियों में लेनदेन शुरू करने और लेनदेन को समाप्त नहीं कर सकते हैं, केवल एक बैंक के भीतर एक सिस्टम के भीतर। तो समस्या को हल करने के लिए सॉफ़्टवेयर में निश्चित रूप से तरीके हैं।
  • सहन करना - अंतिम दृष्टिकोण, जो अक्सर आधुनिक वेब एप्लिकेशन और अन्य अनुप्रयोगों में काम करता है जो डेटा का एक जबरदस्त मात्रा में लेते हैं, बस थोड़ा असंगतता को सहन करना है। एक उदाहरण, यदि हम फेसबुक में एक मित्र फ़ीड के बारे में बात कर रहे हैं, तो यह कोई फर्क नहीं पड़ता कि हर कोई आपकी दीवार को एक साथ अपडेट करता है। अगर ओके, अगर एक व्यक्ति के कुछ सेकंड के लिए कुछ धड़कता है और वे पकड़ लेते हैं। यह अक्सर बहुत सारे सिस्टम डिज़ाइनों में महत्वपूर्ण नहीं होता है कि सब कुछ पूरी तरह से सुसंगत रखा जाए और सभी में एक समान और डेटाबेस के लिए एक ही दृष्टिकोण हो। इसलिए हम कुछ हद तक असंगतता को थोड़ा सहन कर सकते हैं।

Update, findAndModify, $addToSet(एक अद्यतन अंदर), और $push(एक अद्यतन के अंदर) के संचालन के लिए एक एकल दस्तावेज़ के भीतर atomically कार्य करते हैं।


2
मुझे यह उत्तर पसंद आने के बजाय सवाल करना चाहिए कि क्या हमें संबंधपरक DB पर वापस जाना चाहिए। धन्यवाद @xameeramir!
डोनेशियन

3
यदि आप 1 से अधिक सर्वर रखते हैं तो कोड का एक महत्वपूर्ण खंड काम नहीं करेगा, बाहरी वितरित लॉकिंग सेवा का उपयोग करना होगा
अलेक्जेंडर मिल्स

@AlexanderMills क्या आप कृपया विस्तार से बता सकते हैं?
ज़मीर

जवाब यहाँ से वीडियो ट्रांसक्रिप्ट लगता है: youtube.com/watch?v=_Iz5xLZr8Lw
Fritz

मुझे लगता है कि यह तब तक ठीक लगता है जब तक हम एकल संग्रह पर काम करने के लिए प्रतिबंधित नहीं हैं। लेकिन हम अलग-अलग कारण (डॉक आकार या यदि आप संदर्भ का उपयोग कर रहे हैं) के कारण सब कुछ एक ही दस्तावेज़ में नहीं डाल सकते हैं। मुझे लगता है कि फिर हमें लेनदेन की आवश्यकता हो सकती है।
user2488286

24

चेक इस बाहर, Tokutek द्वारा। वे मानगो के लिए एक प्लगइन विकसित करते हैं जो न केवल लेनदेन का वादा करता है बल्कि प्रदर्शन में भी वृद्धि करता है।


@ गोविन्दी बिटलाइनर टोकुटेक को पेरकोना द्वारा अधिगृहीत किया गया है, और आपके द्वारा दिए गए लिंक पर, मुझे किसी भी जानकारी का कोई संदर्भ नहीं दिखता है जो पोस्ट के बाद हुआ है। क्या आप जानते हैं कि उनके प्रयास से क्या हुआ? मैंने पता करने के लिए उस पृष्ठ पर ईमेल पता ईमेल किया।
टायलर कोलियर

आपको विशेष रूप से क्या चाहिए? यदि आपको मोंगोडब पर लागू टॉक तकनीक की आवश्यकता है , तो github.com/Tokutek/mongo को आज़माएं , यदि आपको mysql संस्करण की आवश्यकता है, तो हो सकता है कि उन्होंने इसे अपने
माईसकल के

मैं नोडज के साथ टोकबेक कैसे कर सकता हूं।
मनोज संजीवा

11

यह बात करने के लिए ले आओ: लेन-देन संबंधी अखंडता एक है अगर चाहिए तो MongoDB का उपयोग नहीं करते लेकिन सिस्टम लेनदेन के समर्थन में केवल घटकों का उपयोग करें। गैर-एसीआईडी ​​अनुरूप घटकों के लिए एसीआईडी-समान कार्यक्षमता प्रदान करने के लिए घटक के शीर्ष पर कुछ बनाना बेहद कठिन है। व्यक्तिगत usecases के आधार पर यह किसी भी तरह से लेनदेन और गैर-लेन-देन की कार्रवाइयों में अलग-अलग क्रियाओं को समझ सकता है ...


1
मुझे लगता है कि आप का मतलब है कि NoSQL क्लासिक RDBMS के साथ एक साइडकिक डेटाबेस के रूप में इस्तेमाल किया जा सकता है। मुझे एक ही प्रोजेक्ट में NoSQL और SQL को मिलाने का विचार पसंद नहीं आया। यह जटिलता को बढ़ाता है और संभवतः कुछ गैर तुच्छ समस्याओं का भी परिचय देता है।
नागी

1
NoSQL समाधान शायद ही कभी अकेले उपयोग किया जाता है। दस्तावेज़ भंडार (मोंगो और काउच) शायद इस नियम से एकमात्र अपवाद हैं।
कारोली होर्वाथ

7

अब इसमें क्या दिक्कत है? MongoDB परमाणु अद्यतन केवल एक दस्तावेज़ पर कर सकता है। पिछले प्रवाह में ऐसा हो सकता है कि किसी तरह की त्रुटि हो जाती है और संदेश डेटाबेस में संग्रहीत हो जाता है लेकिन उपयोगकर्ता का संतुलन कम नहीं होता है और / या लेन-देन लॉग नहीं होता है।

यह वास्तव में कोई समस्या नहीं है। आपके द्वारा उल्लिखित त्रुटि या तो तार्किक (बग) या आईओ त्रुटि (नेटवर्क, डिस्क विफलता) है। इस तरह की त्रुटि गैर-सुसंगत स्थिति में लेन-देन रहित और लेन-देन वाले स्टोर दोनों को छोड़ सकती है। उदाहरण के लिए, अगर यह पहले ही एसएमएस भेज चुका है, लेकिन मैसेज स्टोर करते समय त्रुटि हुई है - तो यह एसएमएस भेजने में रोलबैक नहीं कर सकता है, जिसका अर्थ है कि यह लॉग इन नहीं होगा, यूजर बैलेंस कम नहीं होगा आदि।

यहां वास्तविक समस्या यह है कि उपयोगकर्ता दौड़ की स्थिति का लाभ उठा सकता है और अपने शेष राशि की अनुमति से अधिक संदेश भेज सकता है। यह आरडीबीएमएस पर भी लागू होता है, जब तक कि आप बैलेंस फील्ड लॉकिंग (जो एक बड़ी अड़चन होगी) के साथ लेनदेन के अंदर एसएमएस भेजते हैं। MongoDB के लिए एक संभावित समाधान के रूप findAndModifyमें संतुलन को कम करने और इसकी जांच करने के लिए सबसे पहले उपयोग किया जाएगा , अगर यह नकारात्मक अस्वीकृति भेजने और राशि (परमाणु वेतन वृद्धि) को वापस करने के लिए है। यदि सकारात्मक है, तो भेजना जारी रखें और यदि यह राशि वापस करने में विफल रहता है। बैलेंस हिस्ट्री कलेक्शन को बैलेंस फील्ड को फिक्स / वेरीफाई करने में मदद के लिए भी रखा जा सकता है।


इस बेहतरीन जवाब के लिए धन्यवाद! मुझे पता है कि अगर मैं लेन-देन सक्षम स्टोरेज डेटा का उपयोग करता हूं तो एसएमएस प्रणाली के कारण भ्रष्ट हो सकता है जिसके पास मेरा नियंत्रण नहीं है। हालांकि मोंगो के साथ एक मौका है कि डेटा त्रुटि घर में भी हो सकती है। मान लें कि कोड उपयोगकर्ता के बैलेंस को findAndModify से बदल देता है, शेष ऋणात्मक हो जाता है, लेकिन इससे पहले कि मैं गलती को ठीक कर सकूं और आवेदन को पुनः आरंभ करने की आवश्यकता है। मुझे लगता है कि मेरा मतलब है कि मुझे लेनदेन संग्रह के आधार पर दो-चरण की प्रतिबद्धताओं के समान कुछ लागू करना चाहिए और डेटाबेस पर नियमित सुधार की जांच करना चाहिए।
नागी

9
सही नहीं है, यदि आप अंतिम प्रतिबद्ध नहीं करते हैं, तो लेन-देन की दुकानों को वापस रोल किया जाएगा।
कारोली होर्वाथ

9
इसके अलावा, आप एसएमएस नहीं भेजते हैं और फिर डीबी में लॉग इन करते हैं, यह सिर्फ सादा गलत है। पहले डीबी में सब कुछ स्टोर करें और एक अंतिम प्रतिबद्ध करें, फिर आप संदेश भेज सकते हैं। इस बिंदु पर कुछ अभी भी विफल हो सकता है, इसलिए आपको यह जांचने के लिए एक क्रॉन नौकरी की आवश्यकता है कि संदेश वास्तव में भेजा गया था, अगर भेजने की कोशिश नहीं की गई। शायद एक समर्पित संदेश कतार इसके लिए बेहतर होगी। लेकिन पूरी बात उबलती है कि क्या आप ट्रांजेक्शन के तरीके से एसएमएस भेज सकते हैं ...
Karoly Horvath

@NagyI हाँ, मेरा यही मतलब है। स्केलेबिलिटी में आसानी के लिए लेन-देन के लाभों का व्यापार करना होगा। मूल रूप से एप्लिकेशन को विभिन्न संग्रह में किसी भी दो दस्तावेजों की अपेक्षा करनी चाहिए, असंगत स्थिति में हो सकते हैं और इसे संभालने के लिए तैयार हो सकते हैं। @ \ _ यह रोलबैक होगा लेकिन राज्य अब वास्तविक नहीं होगा (संदेश के बारे में जानकारी खो जाएगी)। यह केवल आंशिक डेटा होने की तुलना में बेहतर नहीं है (जैसे कि संतुलन कम हो गया लेकिन कोई संदेश जानकारी या इसके विपरीत नहीं)।
pingw33n

समझा। यह वास्तव में एक आसान बाधा नहीं है। शायद मुझे इस बारे में अधिक सीखना चाहिए कि आरडीबीएमएस सिस्टम कैसे लेनदेन करते हैं। क्या आप किसी प्रकार की ऑनलाइन सामग्री या पुस्तक की सिफारिश कर सकते हैं जहां मैं इन के बारे में पढ़ सकता हूं?
नागी जूल 10'11

6

परियोजना सरल है, लेकिन आपको भुगतान के लिए लेनदेन का समर्थन करना होगा, जिससे पूरी बात मुश्किल हो जाती है। इसलिए, उदाहरण के लिए, सैकड़ों संग्रह (फोरम, चैट, विज्ञापन, आदि ...) के साथ एक जटिल पोर्टल प्रणाली कुछ सम्मान में सरल है, क्योंकि यदि आप एक मंच या चैट प्रविष्टि खो देते हैं, तो कोई भी वास्तव में परवाह नहीं करता है। यदि आप, दूसरे पर, एक भुगतान लेनदेन खो देते हैं जो एक गंभीर मुद्दा है।

इसलिए, यदि आप वास्तव में MongoDB के लिए एक पायलट प्रोजेक्ट चाहते हैं, तो एक चुनें जो उस संबंध में सरल हो ।


समझाने के लिए धन्यवाद। यह सुनकर दुख हुआ। मुझे NoSQL की सादगी और JSON का उपयोग पसंद है। हम ORM के विकल्प की तलाश कर रहे हैं, लेकिन ऐसा लग रहा है कि हमें कुछ समय के लिए इसके साथ रहना चाहिए।
नागी

क्या आप कोई अच्छा कारण दे सकते हैं कि क्यों MongoDB इस कार्य के लिए SQL से बेहतर है? पायलट प्रोजेक्ट थोड़ा मूर्खतापूर्ण लगता है।
कारोली होर्वाथ

मैंने यह नहीं कहा कि MongoDB SQL से बेहतर है। हम बस यह जानना चाहते हैं कि क्या यह SQL + ORM से बेहतर है। लेकिन अब यह स्पष्ट हो रहा है कि वे इस तरह की परियोजनाओं में प्रतिस्पर्धी नहीं हैं।
नागी

6

मान्य कारणों के लिए MongoDB में लेनदेन अनुपस्थित हैं। यह उन चीजों में से एक है जो MongoDB को तेज बनाते हैं।

आपके मामले में, यदि लेन-देन एक जरूरी है, तो मोंगो एक अच्छा फिट नहीं है।

RDMBS + MongoDB हो सकता है, लेकिन इससे जटिलताएं बढ़ जाएंगी और इससे एप्लिकेशन का प्रबंधन और समर्थन करना कठिन हो जाएगा।


1
अब MongoDB का एक वितरण है, जिसे TokuMX कहा जाता है, जो 50x प्रदर्शन सुधार देने के लिए भग्न तकनीक का उपयोग करता है और एक ही समय में पूर्ण ACID लेनदेन का समर्थन देता है: tokutek.com/tokumx-for-mongodb
OCDev

9
कैसे लेन-देन कभी "नहीं" होना चाहिए। जैसे ही आपको कभी 1 सरल मामले की आवश्यकता होती है जहां आपको 2 टेबल को अपडेट करने की आवश्यकता होती है मोंगो अचानक एक अच्छा फिट नहीं रह जाता है? यह बहुत सारे उपयोग मामलों को बिल्कुल नहीं छोड़ता है।
Mr_E

1
@ म_ई सहमत हैं, इसीलिए मोंगोबडी थोड़े गूंगे हैं :)
अलेक्जेंडर मिल्स

6

शायद यह सबसे अच्छा ब्लॉग है जिसे मैंने लेन-देन को लागू करने के बारे में पाया है जैसे कि मैंगोडब के लिए सुविधा!

सिंकिंग फ़्लैग: मास्टर दस्तावेज़ से अधिक डेटा कॉपी करने के लिए सर्वोत्तम

नौकरी कतार: बहुत सामान्य उद्देश्य, 95% मामलों को हल करता है। अधिकांश प्रणालियों को वैसे भी कम से कम एक नौकरी की कतार की आवश्यकता होती है!

दो चरण की प्रतिबद्धता: यह तकनीक सुनिश्चित करती है कि प्रत्येक इकाई को हमेशा एक सुसंगत स्थिति में लाने के लिए आवश्यक सभी जानकारी होनी चाहिए

लॉग रिकॉन्लेशन: सबसे मजबूत तकनीक, वित्तीय प्रणालियों के लिए आदर्श

वर्जनिंग: अलगाव प्रदान करता है और जटिल संरचनाओं का समर्थन करता है

अधिक जानकारी के लिए इसे पढ़ें: https://dzone.com/articles/how-implement-robust-and


कृपया अपने उत्तर के भीतर प्रश्न का उत्तर देने के लिए आवश्यक लिंक किए गए संसाधन के प्रासंगिक भागों को शामिल करें। जैसा कि, आपका जवाब सड़ांध को जोड़ने के लिए अतिसंवेदनशील है (अर्थात यदि लिंक की गई वेबसाइट नीचे चली जाती है या आपका उत्तर बदल जाता है तो संभवतः बेकार है)।
मेक

सुझाव के लिए @mech धन्यवाद
वैभव

4

यह देर हो चुकी है लेकिन लगता है कि इससे भविष्य में मदद मिलेगी। मैं इस समस्या को हल करने के लिए एक कतार बनाने के लिए रेडिस का उपयोग करता हूं ।

  • आवश्यकता:
    शो 2 एक्शन के नीचे की छवि को समवर्ती रूप से निष्पादित करने की आवश्यकता है, लेकिन चरण 2 और एक्शन के चरण 3 को एक्शन 2 के शुरुआती चरण 2 से पहले खत्म करने की आवश्यकता है या इसके विपरीत (एक चरण एक अनुरोध हो सकता है REST एपीआई, एक डेटाबेस अनुरोध या जावास्क्रिप्ट का निष्पादन ... )। यहां छवि विवरण दर्ज करें

  • कैसे एक कतार आपकी मदद करती है
    क्यू सुनिश्चित करें कि प्रत्येक फ़ंक्शन के बीच lock()और release()कई फ़ंक्शन एक ही समय में नहीं चलेंगे, उन्हें अलग-थलग करें।

    function action1() {
      phase1();
      queue.lock("action_domain");
      phase2();
      phase3();
      queue.release("action_domain");
    }
    
    function action2() {
      phase1();
      queue.lock("action_domain");
      phase2();
      queue.release("action_domain");
    }
  • एक कतार का निर्माण कैसे करें
    मैं केवल इस बात पर ध्यान केंद्रित करूंगा कि बैकएंड साइट पर एक कतार बनाते समय रेस कॉन्डिटन भाग से कैसे बचें । यदि आप कतार के मूल विचार को नहीं जानते हैं, तो आइए यहां
    नीचे दिए गए कोड केवल अवधारणा दिखाते हैं, आपको सही तरीके से कार्यान्वयन की आवश्यकता है।

    function lock() {
      if(isRunning()) {
        addIsolateCodeToQueue(); //use callback, delegate, function pointer... depend on your language
      } else {
        setStateToRunning();
        pickOneAndExecute();
      }
    }
    
    function release() {
      setStateToRelease();
      pickOneAndExecute();
    }

लेकिन आपको जरूरत है isRunning() setStateToRelease() setStateToRunning() अलग-थलग अन्यथा आप फिर से दौड़ की स्थिति का सामना करते हैं। ऐसा करने के लिए मैं ACID उद्देश्य और स्केलेबल के लिए रेडिस का चयन करता हूं ।
Redis दस्तावेज़ के बारे में बात है कि यह लेनदेन है:

लेन-देन के सभी आदेश क्रमबद्ध और क्रमिक रूप से निष्पादित किए जाते हैं। ऐसा कभी नहीं हो सकता है कि किसी अन्य क्लाइंट द्वारा जारी किया गया एक अनुरोध रेडिस लेनदेन के निष्पादन के बीच में परोसा जाता है। यह गारंटी देता है कि आदेशों को एक पृथक ऑपरेशन के रूप में निष्पादित किया जाता है।

पी / एस:
मैं रेडिस का उपयोग करता हूं क्योंकि मेरी सेवा पहले से ही इसका उपयोग करती है, आप ऐसा करने के लिए किसी अन्य तरीके के समर्थन का उपयोग कर सकते हैं।
action_domainमेरी कोड में के लिए जब आप उपयोगकर्ता एक के उपयोगकर्ता एक ब्लॉक कार्रवाई 2 से केवल कार्रवाई 1 कॉल की जरूरत है, अन्य उपयोगकर्ता को ब्लॉक नहीं करती ऊपर है। प्रत्येक उपयोगकर्ता के ताला के लिए विचार एक अद्वितीय कुंजी है।


आपको अधिक अपवोट प्राप्त हुआ होगा आपका स्कोर पहले से ही अधिक था। यहाँ सबसे ज्यादा यही लगता है। प्रश्न के संदर्भ में आपका उत्तर उपयोगी है। मैंने तुम्हें उभार दिया है।
मुकुस

3

अब MongoDB 4.0 में लेनदेन उपलब्ध हैं। यहाँ नमूना

// Runs the txnFunc and retries if TransientTransactionError encountered

function runTransactionWithRetry(txnFunc, session) {
    while (true) {
        try {
            txnFunc(session);  // performs transaction
            break;
        } catch (error) {
            // If transient error, retry the whole transaction
            if ( error.hasOwnProperty("errorLabels") && error.errorLabels.includes("TransientTransactionError")  ) {
                print("TransientTransactionError, retrying transaction ...");
                continue;
            } else {
                throw error;
            }
        }
    }
}

// Retries commit if UnknownTransactionCommitResult encountered

function commitWithRetry(session) {
    while (true) {
        try {
            session.commitTransaction(); // Uses write concern set at transaction start.
            print("Transaction committed.");
            break;
        } catch (error) {
            // Can retry commit
            if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes("UnknownTransactionCommitResult") ) {
                print("UnknownTransactionCommitResult, retrying commit operation ...");
                continue;
            } else {
                print("Error during commit ...");
                throw error;
            }
       }
    }
}

// Updates two collections in a transactions

function updateEmployeeInfo(session) {
    employeesCollection = session.getDatabase("hr").employees;
    eventsCollection = session.getDatabase("reporting").events;

    session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );

    try{
        employeesCollection.updateOne( { employee: 3 }, { $set: { status: "Inactive" } } );
        eventsCollection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } );
    } catch (error) {
        print("Caught exception during transaction, aborting.");
        session.abortTransaction();
        throw error;
    }

    commitWithRetry(session);
}

// Start a session.
session = db.getMongo().startSession( { mode: "primary" } );

try{
   runTransactionWithRetry(updateEmployeeInfo, session);
} catch (error) {
   // Do something with error
} finally {
   session.endSession();
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.