2012-06-13 12 views
12

उदाहरण: व्यवसाय नियम बताते हैं कि ऑर्डर देने पर ग्राहक को एक पुष्टिकरण संदेश (ईमेल या समान) प्राप्त करना चाहिए।सीक्यूआरएस - कब पुष्टि संदेश भेजना है?

का कहना है कि एक NewOrderRegisteredEvent डोमेन से भेजा जाता है और एक घटना श्रोता पुष्टि संदेश के द्वारा भेजे जाने वाले द्वारा उठाया जाता है देता है। जब ऐसा किया जाता है तो कुछ अन्य घटना हैंडलर अपवाद फेंकता है या कुछ और गलत हो जाता है और काम की इकाई वापस लुढ़क जाती है। हमने अब उपयोगकर्ता को वापस लुढ़का हुआ कुछ चीज़ के लिए एक पुष्टिकरण संदेश भेजा है।

इस तरह की समस्याओं को हल करने के "cqrs" तरीका क्या है जहां आप काम की इकाई के बाद कुछ करना चाहते हैं? एक और जटिल कारक घटनाओं को फिर से खेल रहा है। जब भी मैं एक नया दृश्य/प्रक्षेपण बनाने के लिए रिकॉर्ड की गई घटनाओं को फिर से चलाता हूं, तो मैं पुराने पुष्टिकरण संदेशों को दोबारा नहीं भेजना चाहता हूं।

मेरा सबसे अच्छा सिद्धांत अब तक: मैंने अभी तक सीकर्स की आकर्षक दुनिया को देखना शुरू कर दिया है और यह सोच रहा था कि यह ऐसा कुछ है जिसे गाथा के रूप में लागू किया जाएगा? यदि एक गाथा एक राज्य मशीन की तरह है जहां प्रत्येक संक्रमण केवल एक ही समय में हो सकता है तो मुझे लगता है कि इस समस्या को हल करेगा? मैं सिर्फ visualizing कैसे इस आदेश बस और डोमेन की घटनाओं के साथ एक साथ फिट होगा एक कठिन समय है ..

+1

"ईमेल भेजें" कार्य को एक संदेश बनाएं। यदि उउ वापस रोल करता है, तो संदेश प्रेषण (टिकाऊ भंडारण के लिए) करता है। कुछ और संदेश उठाता है और ईमेल चीज करता है। बीटीडब्ल्यू, सीकर्स से संबंधित नहीं। सादा वितरित कंप्यूटिंग सामान्य ज्ञान। –

+0

इवेंट रीप्ले के लिए, जो कभी भी इस तरह के व्यवहार को प्रेरित नहीं करता है। यदि आपका निहितार्थ है। करता है, आप इसे गलत कर रहे हैं। –

+0

यह समझ में आता है, लेकिन मुझे इसमें एक cqrs संदर्भ में दिलचस्पी है। एक "संदेश" क्या है? और कौन/इसे उठाएगा, और कब? आउटगोइंग संचार का ट्रैक रखने के लिए एक और भंडारण तंत्र शुरू करने से बचने के लिए इवेंट स्टोर में लाभ उठाना अच्छा होगा। – Kimble

उत्तर

16
  1. एक ईवेंट लेनदेन पूरा होने के बाद ही होना चाहिए। अगर कुछ गलत हो जाता है और रोलबैक होता है, तो घटना बाहरी दृष्टिकोण से नहीं होती है। इसलिए इसे बिल्कुल प्रकाशित नहीं किया जाना चाहिए। यद्यपि यदि आवश्यक हो तो OrderRegistrationFailed ईवेंट प्रकाशित किया जा सकता है।

  2. आप मेल नहीं भेजना चाहते हैं जब तक आदेश को सफलतापूर्वक निष्पादित नहीं किया जाता है।

    कमांड हैंडलर - जैसा कि किसी अन्य उत्तर में प्रस्तावित किया गया है, पहले कुछ कारणों से गलत जगह होगी: कुछ परिस्थितियों में कमांड हैंडलर यह बताने में सक्षम नहीं होगा कि आदेश अंततः सफल होगा या नहीं। कमांड हैंडलर मेल भेजने का आह्वान करने से कमांड हैंडलर के अंदर प्रक्रिया ज्ञान भी लगाएगा, जो एसआरएम को तोड़ देगा और आवेदन परत के साथ बहुत कड़े दो व्यवसाय नियमों को तोड़ देगा।

    इस तथ्य के बाद मेल भेजा जाना चाहिए, यानी एक ईवेंट हैंडलर से।

    इस हैंडलर को रीप्ले के दौरान फायरिंग से रोकने के लिए, आप इसे पंजीकृत नहीं कर सकते हैं। यह आपके आवेदन की जांच के समान काम करता है। आप केवल उन हैंडलर को पंजीकृत करते हैं जिन्हें आपको वास्तव में चाहिए।

    • उत्पादन प्रणाली -> सभी ईवेंट हैंडलर्स रजिस्टर
    • टेस्ट -> रजिस्टर केवल परीक्षण किया ईवेंट हैंडलर्स
    • खेलना -> रजिस्टर केवल प्रक्षेपण/असमान्यीकरण संचालकों

एक और - यहां तक ​​कि थोड़ा अधिक जटिल, हालांकि थोड़ा अधिक जटिल - संभावना SagaNewOrderRegisteredEvent को संभालने और अनुमोदन के लिए SendMail आदेश जारी करें ओप्रीट बाध्य संदर्भ (धन्यवाद, Yves Reynhout, प्रश्न की टिप्पणियों में इसे इंगित करने के लिए)।

+1

यह स्टैक ओवरफ्लो पर यहां मिले सर्वोत्तम उत्तरों में से एक है! घटनाओं को सफलतापूर्वक ईवेंट लॉग में सफलतापूर्वक लिखे जाने के बाद डोमेन ईवेंट कहीं भी buffered किया जाएगा और केवल डोमेन (अनुमान/डी-सामान्यीकृतकर्ताओं के लिए) के बाहर प्रकाशित किया जाएगा? मुझे लगता है कि इवेंट स्टोर में लिखना एक कमांड हैंडलर/इंटरसेप्टर द्वारा शुरू किए गए लेनदेन (आमतौर पर) के अंदर होता है? – Kimble

+0

असल में हाँ, एक या एकाधिक ईवेंट/एस (या तो एक ईवेंट लॉग या इवेंट स्टोर में, दोनों को भ्रमित न करने के लिए सावधान रहें) लेनदेन का आखिरी हिस्सा होगा। सफल भंडारण के बाद ही/उन्हें प्रेषित और संसाधित किया जाएगा, संभवतः असीमित रूप से भी। –

+0

इवेंट लॉग और स्टोर के बीच क्या अंतर है? मुझे यकीन है कि मैंने देखा है कि cqrs के बारे में पढ़ने के दौरान उन लोगों को एक दूसरे के साथ उपयोग किया जा रहा है .. – Kimble

2

दो संभावना समाधान

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

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

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

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

+0

लंबे उत्तर के लिए धन्यवाद! वितरित लेनदेन एक दर्द है। समाधान संख्या दो के संबंध में, क्या इसमें भेजे गए ईमेल का ट्रैक रखने के लिए एक नया स्टोरेज तंत्र शुरू करना शामिल होगा, या इसके लिए ईवेंट स्टोर का लाभ उठाना आम है? मुझे इवेंट हैंडलर अपनी घटनाओं को प्रकाशित करने के साथ कुछ संभावित समस्याएं देखता है .. विशेष रूप से प्लेबैक के दौरान जहां "ईमेल भेजा गया" ईवेंट घटना के बाद पहली बार ईमेल को ट्रिगर करने के बाद आएगा। – Kimble

+0

यदि आप वास्तव में लेनदेन संबंधी ई-मेल भेजना चाहते हैं, तो आपको किसी भी तरह से इसे संभालना होगा। संभवतः डिस्क पर सफलतापूर्वक भेजे गए ईमेल की पहचान सहेजकर।लेकिन यदि आप कुछ कतार में आवश्यक संदेश लिखते हैं तो अधिकांश वाणिज्यिक ग्रेड ईमेल ऑपरेशन गारंटी वितरण नहीं करते हैं? –

+0

वास्तव में ट्रांजैक्शनल ई-मेल भेजना अभी दायरे से बाहर है। मैं इस बारे में उत्सुक था कि सीकर्स में इस समस्या का सामना कैसे किया गया, खासकर इवेंट रीप्ले के साथ। लेकिन, हाँ, एक कतार पर ईमेल डालना और ईवेंट स्टोर में एक सहसंबंध आईडी संग्रह करना डिलीवरी की गारंटी में एक लंबा रास्ता तय करेगा। – Kimble