इवेंट सोर्सिंग, एक घटना, दो समुच्चय की स्थिति बदल गई


10

मैं डीडीडी और संबंधित विषयों के तरीके सीखने की कोशिश कर रहा हूं। मैं "बैंक" को लागू करने के लिए सरल बंधे हुए संदर्भ के विचार के साथ आया था: खाते हैं, पैसा जमा किया जा सकता है, निकाला जा सकता है और उनके माध्यम से स्थानांतरित किया जा सकता है। परिवर्तनों का इतिहास रखना भी महत्वपूर्ण है।

मैंने खाता इकाई की पहचान की है और उस घटना में सोर्सिंग के लिए अच्छा होगा कि वह इसमें बदलावों पर नज़र रखे। अन्य संस्थाएँ या मान ऑब्जेक्ट समस्या के लिए अप्रासंगिक हैं, इसलिए मैं उनका उल्लेख नहीं करूँगा।

जमा और निकासी पर विचार करते समय - यह अपेक्षाकृत सरल है, क्योंकि केवल एक समग्र रूपांतर है।

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

मेरा प्रश्न है - मैं उन तीन सिद्धांतों को एक साथ कैसे ला सकता हूं: "एक समग्र एक लेनदेन", "घटना-> कुल में परिवर्तन" और "समवर्ती संशोधन रोकथाम"?

जवाबों:


7

जब यह अलग हो जाता है, तो दो - दो समुच्चय को एक MoneyTransferred घटना द्वारा संशोधित किया जाना चाहिए।

पैसा ट्रांसफर करना लीडर्स को अपडेट करने से अलग काम है।

MoneyTransferred
AccountCredited
AccountDebited

मेरे लिए इस ढीलेपन को तोड़ने वाली कवायद यह महसूस कर रही थी कि AccountOverdrawnयह एक घटना है, यह इस विनिमय में अन्य प्रतिभागियों की परवाह किए बिना खाते की स्थिति का वर्णन करता है, इसलिए इसे बनाने वाले खाते के खिलाफ कमांड रन होना चाहिए।

आप यथोचित रूप AccountOverdrawnसे पढ़े गए मॉडल से स्थिति प्राप्त नहीं कर सकते हैं, क्योंकि आप संभवतः यह नहीं जान सकते हैं कि क्या आपने अभी तक की सभी घटनाओं को देखा है - केवल किसी भी क्षण में केवल इतिहास का पूरा दृश्य है।

उत्तर, निश्चित रूप से, सर्वव्यापी भाषा में सही है - खातों को अपने ग्राहकों को बैंक के दायित्वों को प्रतिबिंबित करने के लिए क्रेडिट या डेबिट किया जाता है।

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

मैं पूरी तरह से निश्चित नहीं हूं जो इस प्रकार है, क्योंकि आपके पास (इस तरह के मामलों के लिए) एक प्राकृतिक सहसंबंध पहचानकर्ता है, जो कि लेनदेन आईडी है।

दूसरी बात - इसका मतलब है कि मुझे गाथा जैसी किसी चीज का उपयोग करने की आवश्यकता है।

थोड़ी अलग वर्तनी: आपको कुछ ऐसा चाहिए जो मनुष्य को सही आदेशों को भेजने वाला हो

कम से कम दो तरीके हैं जो आप कर सकते हैं। एक ग्राहक के लिए सुनने वाला होगा MoneyTransferred, और दो कमांडरों को भेजने वाला होगा।

एक अन्य विकल्प एक अलग एग्रीगेट के रूप में लेन-देन के प्रसंस्करण को ट्रैक करना होगा - इसे उन सभी चीजों की एक चेकलिस्ट के रूप में सोचें, जो लेन-देन के बाद से होने की आवश्यकता है। इसलिए एक MoneyTransferredईवेंट हैंडलर प्रोसेसट्रांसपैक्टेशन को भेजता है, जो शेड्यूल करने के लिए काम करता है और चेक करता है कि क्या काम पूरा हो चुका है।


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

यह नहीं है -> AccountCredited और AccoundDebited तो MoneyTransferred ? पहला समाधान दोनों एग्रीगेट्स को एक ट्रांजेक्शन में अपडेट करता है ( किसी भी प्रकार की स्थिरता की गारंटी नहीं )? ऐसा कोई समुच्चय भी नहीं है जो MoneyTransferred -> कोई सहसंबंध प्रकाशित न कर सके । दूसरा समाधान बेहतर प्रतीत होता है - ProcessTransaction MoneyTransferred को प्रकाशित कर सकता है और एक लेन-देन में कई समग्र संशोधन से बचने के लिए मैं लेनदेन करने के बाद खाते से ईवेंट प्रकाशित कर सकता हूं । नकचढ़ा होने के लिए क्षमा करें। शुरुआत के लिए समझना मुश्किल है - केवल एक पैटर्न w / o अन्य का उपयोग नहीं कर सकते।
कैस्केकी

1

लेन-देन-आधारित खातों को समझने में एक महत्वपूर्ण विवरण: balanceविशेषता accountवास्तव में एक प्रकार का भाज्य है। यह सुविधा के लिए है। वास्तव में, किसी खाते का शेष उसके लेन-देन का योग है, और आपको शेष राशि के लिए स्वयं खाते की आवश्यकता नहीं है ।

इसे ध्यान में रखते असर, एक पैसा स्थानांतरित करने का कार्य अद्यतन करने के लिए नहीं होना चाहिए account, लेकिन में डालने के लिए transaction

यह कहा जा रहा है, एक और महत्वपूर्ण नियम है: जोड़ने के कार्य को एक transactionपरमाणु से अद्यतन होना चाहिए (एक असामान्य संतुलन क्षेत्र) account

अब अगर मैं समुच्चय की डीडीडी अवधारणा को समझता हूं, तो निम्नलिखित प्रासंगिक लगता है:

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

इसलिए डीडीडी डिजाइन के संदर्भ में मैं सुझाव दूंगा:

  1. स्थानांतरण का प्रतिनिधित्व करने के लिए एक समुच्चय है

  2. कुल निम्नलिखित वस्तुओं से बना है: स्थानांतरण (मूल वस्तु); रूट ऑब्जेक्ट दो लेनदेन सूचियों (प्रत्येक खाते के लिए एक) से जुड़ा हुआ है; और प्रत्येक लेन-देन सूची एक खाते से जुड़ी हुई है।

  3. स्थानांतरण के सभी उपयोग को रूट ऑब्जेक्ट ( transfer) द्वारा ध्यान दिया जाना चाहिए ।

यदि आप अतुल्यकालिक स्थानांतरण समर्थन को लागू करने की कोशिश कर रहे हैं, तो आपके मुख्य कोड को "लंबित" स्थिति में, स्थानांतरण बनाने के बारे में चिंता करनी चाहिए। आपके पास एक और धागा या एक नौकरी हो सकती है जो वास्तव में पैसे को स्थानांतरित करती है (लेन-देन के इतिहास में डालने, और इसलिए संतुलन को अपडेट करना) और "पोस्ट" करने के लिए स्थानांतरण सेट करता है।

यदि आप वास्तविक समय को लागू करना चाहते हैं, तो हस्तांतरण लेनदेन को रोकना, तो व्यापार तर्क को एक बनाना चाहिए transferऔर वह वस्तु वास्तविक समय में अन्य गतिविधियों का समन्वय करेगी।

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

(वास्तविक दुनिया में, बैंक खातों में एक मेमो पोस्ट की अवधारणा है जो एक आलसी दो-चरण प्रतिबद्ध की अवधारणा का समर्थन करती है। मेमो पोस्ट का निर्माण हल्का और आसान है, और यह भी बिना मुद्दे के वापस लुढ़काया जा सकता है। रूपांतरण मेमो पोस्ट एक कठिन पोस्ट के लिए है जब पैसा वास्तव में चलता है - यह वापस नहीं लुढ़का जा सकता - और दो चरण की प्रतिबद्धताओं के दूसरे चरण का प्रतिनिधित्व करता है, सभी सत्यापन नियमों की जाँच के बाद ही होता है)।


0

मैं इस समय सीखने की अवस्था में हूं। कार्यान्वयन के दृष्टिकोण से, यह है कि मुझे लगता है कि आप यह कार्रवाई करेंगे।

डिस्पैच TransferMoneyCommand जो घटनाओं के बाद उठता है [MoneyTransferEvent, AccountDebitedEvent]

ध्यान दें कि इससे पहले कि ये घटनाएँ बढ़ें, सतही आदेश सत्यापन और डोमेन तर्क सत्यापन की आवश्यकता होगी, क्या खाते में पर्याप्त संतुलन है?

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

डेटाबेस में घटनाओं को सफलतापूर्वक सहेजे जाने के बाद आप उन दो घटनाओं को प्रकाशित कर सकते हैं जिन्हें उठाया गया था।

खाताधारक भुगतानकर्ता के खाते से धन निकाल देगा (अद्यतन स्थिति और संबंधित दृश्य / प्रक्षेपण मॉडल)

MoneyTransferEvent सागा / प्रोसेस मैनेजर शुरू करता है।

गाथा / प्रक्रिया प्रबंधक का कार्य भुगतानकर्ता के खाते को क्रेडिट करने का प्रयास करना होगा, अगर यह विफल हो जाता है, तो उसे शेष राशि को भुगतानकर्ता को वापस करने की आवश्यकता होगी।

सागा / प्रक्रिया प्रबंधक एक CreditAccountCommand प्रकाशित करेगा जो कि आदाता के खाते में लागू होता है और यदि खाताधारक की तुलना में सफल होता है तो उठाया जाएगा।

एक इवेंट सोर्सिंग दृष्टिकोण से, यदि आप इस क्रिया को उलटना चाहते हैं, तो इस लेन-देन की सभी घटनाओं का मूल ट्रांसफरमनीकोमैंड के रूप में सहसंबंध / कार्य आईडी होगा, जिसका उपयोग आप पूर्ववत / उलट परिचालन के लिए घटनाओं को बढ़ाने के लिए कर सकते हैं।

उपरोक्त किसी भी मुद्दे या संभावित सुधारों का सुझाव देने के लिए स्वतंत्र महसूस करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.