डीडीडी, सागा और इवेंट-सोर्सिंग: क्या एक कम्पेनसेट एक्शन केवल इवेंट स्टोर पर डिलीट हो सकता है?


15

मुझे एहसास है कि उपरोक्त प्रश्न शायद कुछ 'क्या ??' उठता है, लेकिन मुझे समझाने की कोशिश करें:

मैं संबंधित अवधारणाओं के एक जोड़े पर अपना सिर लपेटने की कोशिश कर रहा हूं, मूल रूप से इवेंट-सोर्सिंग (एक डीडीडी-अवधारणा के साथ संयोजन में सागा-पैटर्न ( http://www.rgoelines.com/Files/SOAPatterns/Saga.pdf ) : http://en.wikipedia.org/wiki/Domain-driven_design )

एक अच्छी पोस्ट जो इसे एक साथ लपेटती है: https://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/

मुझे एक मिनट में सवाल मिल रहा है, लेकिन मुझे लगता है कि मुझे यह समझने की कोशिश करनी होगी कि मैं इसे पहले क्या समझता हूं (जो कि अच्छी तरह से गलत हो सकता है, इसलिए कृपया सही है अगर ऐसा है तो) क्योंकि यह अच्छी तरह से प्रभावित हो सकता है इसलिए मैं प्रश्न के साथ शुरू करने के लिए पूछ रहा है:

  1. सागा पैटर्न एक प्रकार का ब्रोकर है, जिसने एक एक्शन दिया (एंड-यूज़र, स्वचालित, आदि। अनिवार्य रूप से कुछ भी जो डेटा को बदलने जा रहा है) उस एक्शन को व्यावसायिक गतिविधियों में विभाजित करता है और इन गतिविधियों में से प्रत्येक को मैसेज बस में संदेश के रूप में भेजता है जो बदले में इसे संबंधित एकत्रित जड़ों को भेजता है जिसका ध्यान रखा जाना चाहिए।
  2. ये समग्र जड़ें पूरी तरह से स्वायत्त रूप से संचालित हो सकती हैं (चिंताओं का अच्छा पृथक्करण, महान मापनीयता, आदि)
  3. एक सागा-उदाहरण में स्वयं कोई व्यावसायिक तर्क नहीं होता है, जो कि एग्रीगेट जड़ों में निहित है जो इसे गतिविधियों को भेजता है। गाथा में निहित एकमात्र 'तर्क' 'प्रक्रिया'-तर्क है, (अक्सर एक स्टेटमाइन के रूप में लागू किया जाता है), जो प्राप्त किए गए कार्यों (साथ ही साथ अनुवर्ती घटनाओं) के आधार पर निर्धारित करता है कि क्या करना है (यानी: क्या गतिविधियों को भेजना है)
  4. सागा-पैटर्न एक प्रकार का वितरित लेनदेन पैटर्न लागू करता है। Ie: जब कुल जड़ों में से एक (जो फिर से स्वायत्त रूप से काम करता है, प्रत्येक माताओं के अस्तित्व को जाने बिना) विफल हो जाता है, तो पूरी कार्रवाई को वापस रोल करना पड़ सकता है।
  5. सागा को वापस उनकी गतिविधि की रिपोर्ट के पूरा होने पर, सभी मूल जड़ों को लागू किया जाता है। (सफलता के मामले में भी त्रुटि)
  6. मामले में सभी समुच्चय जड़ें एक सफलता लौटाती हैं, आंतरिक स्टेटमाइन यदि सागा निर्धारित करता है कि आगे क्या करना है (या इसे करना है)
  7. असफलता के मामले में, सागा सभी एग्रीगेट जड़ों को जारी करता है, जिन्होंने अंतिम कार्रवाई में एक तथाकथित मुआवजा एक्शन लिया, अर्थात: एग्रीगेट प्रत्येक रूट की अंतिम कार्रवाई को पूर्ववत करने की कार्रवाई।
  8. यह केवल 'माइनस 1 वोट' हो सकता है अगर एक्शन "प्लस 1 वोट" था, लेकिन यह पिछले संस्करण के लिए एक ब्लॉगपोस्ट को पुनर्स्थापित करने की तरह अधिक जटिल हो सकता है।
  9. ईवेंट-सोर्सिंग (दोनों को मिलाते हुए ब्लॉगपोस्ट देखें) का उद्देश्य उन प्रत्येक गतिविधियों के परिणामों को सहेजना है, जो प्रत्येक केंद्रीकृत इवेंट स्टोर में किए गए एग्रीगेट रूट्स (परिवर्तन इस संदर्भ में 'ईवेंट' कहलाते हैं)
  10. यह ईवेंट स्टोर 'सत्य का एकल संस्करण' है और इसका उपयोग स्टोर की गई घटनाओं (अनिवार्य रूप से ईवेंट लॉग की तरह) को पुन: व्यवस्थित करके सभी संस्थाओं की स्थिति को फिर से लिखने के लिए किया जा सकता है।
  11. दोनों को मिलाना (यानी: समग्र जड़ों को उपयोग करने के लिए इवेंट-सोर्स को आउटसोर्स करने से पहले सागा को रिपोर्ट करने से बचाने के लिए) बहुत सारी अच्छी संभावनाएं देता है, जिनमें से एक मेरे सवाल से चिंतित है ...

मुझे लगा कि मुझे अपने कंधे से उतरने की जरूरत है, क्योंकि एक बार में बहुत कुछ समझ में आता है। इस संदर्भ / मानसिकता को देखते हुए (यदि गलत हो तो कृपया सही करें)

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

इससे मुझे बहुत फायदा होगा (और इस संयोजन का एक और बड़ा फायदा होगा) लेकिन जैसा कि मैंने कहा कि मैं इन अवधारणाओं को गलत / अधूरी समझ के आधार पर बना रहा हूं।

मुझे आशा है कि यह बहुत लंबे समय तक प्रसारित नहीं हुआ।

धन्यवाद।

जवाबों:


9

आपको अपने ईवेंट स्टोर से ईवेंट को नहीं हटाना चाहिए। ये कुछ इस तरह का प्रतिनिधित्व करते हैं। यदि अब कुछ होता है, तो आपको यह भी पता होना चाहिए, इसलिए एक ऐसी घटना जोड़ें जो आपके कुल को कुछ पिछली स्थिति में वापस जाने के लिए मजबूर कर दे। यह आपके डेटाबेस से जानकारी को हटाने के लिए एक दया है।

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

जहां तक ​​गाथा की बात है, हर बात सही है, जहां तक ​​मैं खुद को जानता हूं। आपको गाथा को एक राज्य मशीन के रूप में सोचना चाहिए। यह केवल वही करता है।

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

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


किस कुल को किस राज्य में वापस जाना होगा? क्या इसे इवेंट-स्टोर या किसी चीज़ के खिलाफ क्वेरी करने की अनुमति होगी?
गीर्ट-जन

यह वापस नहीं होना चाहिए, लेकिन एक और घटना जोड़ें। यह एक कमान है जो गाथा कुछ करने के लिए कुल को बताने के लिए जारी कर रही है। इस कार्रवाई में से एक घटना होगी।
आर्थिस

हाँ मैं समझता हूं। "रिवर्ट" शायद बीमार था। निम्नलिखित पर विचार करें: मैं मॉडलिंग के लिए साग के साथ इवेंट सोर्सिंग का उपयोग करना चाह सकता हूं, अन्य चीजों के साथ, दस्तावेज़ प्रकाशन / अनुमोदन प्रवाह। क्या होगा अगर एक संपादक ने एक चेंजब्लॉगब्लॉगबॉडी-एक्शन भेजा है जो अंततः एक BlogBodyChanged-event के रूप में इवेंट स्टोर पर बना रहता है। बाद में, किसी कारण के लिए, एक मुआवजा कार्रवाई जारी की जाती है। एग्रीगेट को कैसे पता चलेगा कि ब्लॉग बॉडी के कंटेंट में आग लगने की घटना की भरपाई क्या होती है क्योंकि यह चेंजब्लॉगब्लॉडी-एक्शन जारी होने से ठीक पहले था?
गीर्ट-जान

यह आपके व्यावसायिक नियमों पर निर्भर करता है। या तो, एक आसान निर्धारण है: समग्र रूट जानता है कि इस तरह के मामले में, आप ऐसा करते हैं, या विकल्प बहुत जटिल है जो प्रोग्रामेटिक रूप से किया जाना है (इसलिए विकास लागत बहुत अधिक है) और इसलिए, आप इसे कुछ उपयोगकर्ता को प्रस्तावित कर सकते हैं, जो अलग कार्रवाई के बीच चयन कर सकते हैं।
आर्थिस

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

6

पूर्णता के लिए मैंने मार्टिन फाउलर से राज्य को वापस लाने के तरीकों के बारे में एक प्रासंगिक स्निपेट शामिल करने का सोचा:

अपने आप को आगे की ओर खेलते हुए घटनाओं के साथ-साथ, यह अक्सर उनके लिए भी उपयोगी होता है कि वे खुद को उलट सकें।

रिवर्सल सबसे सीधा है जब घटना को अंतर के रूप में डाला जाता है। इसका एक उदाहरण "मार्टिन के खाते में $ 10 जोड़ना" होगा, "मार्टिन के खाते को $ 110 पर सेट करना" के विपरीत। पूर्व मामले में मैं केवल $ 10 घटाकर रिवर्स कर सकता हूं, लेकिन बाद के मामले में मुझे खाते के पिछले मूल्य को फिर से बनाने के लिए पर्याप्त जानकारी नहीं है।

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

प्रेषक: http://martinfowler.com/eaaDev/EventSourcing.html


1

सैद्धांतिक रूप:

  • घटना कुछ ऐसी है अतीत को बदला नहीं जा सकता।
  • आज्ञा कुछ करना है। आदेश नहीं हो सकता है (अस्वीकार किया जा सकता है)।

हम केवल एक और कमांड (कम्पेनसेट एक्शन) को क्रियान्वित करके अपने भविष्य की स्थिति को बदल सकते हैं, जिसके परिणामस्वरूप एप्लिकेशन के इवेंट बदलने की स्थिति में परिणाम होना चाहिए।

प्रश्न को "डी-कन्फ्यूज" करने के लिए, इस वाक्यांश के बारे में सोचें "अंतिम घटना को हटाएं":

  • क्या होगा यदि अंतिम घटना वह नहीं है जिसे हटाया जाना है? यदि डिलीट होने के बाद अन्य घटनाएँ हुईं तो क्या होगा? इन घटनाओं को भी बदलना होगा (क्योंकि उनके आधार की स्थिति को उनके सामने घटना को हटाकर बदल दिया गया होगा)।
  • क्या होगा अगर ईवेंट को बाहरी सिस्टम में भेजा गया? आपके पास किसी अन्य घटना को भेजने के अलावा इसके राज्य को सही करने के लिए कोई पहुंच नहीं हो सकती है।

संक्षेप में, आपके पास CQRS पैटर्न में घटनाओं को हटाने का कोई विकल्प नहीं है।

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


0

गीर्ट-जान, मुझे भी लगता है कि मुआवजे की कार्रवाई केवल इसी घटना को हटा सकती है। यह समझ में आता है और यह इवेंट सोर्सिंग डिज़ाइन पैटर्न का एक और लाभ दिखाता है: कॉम्पेंसेटिंग ट्रांजेक्शन डिज़ाइन पैटर्न का आसान कार्यान्वयन।

कुछ का कहना है कि घटना को हटाना इवेंट सोर्सिंग या CQRS के "सिद्धांतों" का उल्लंघन करता है। मुझे लगता है कि यह एक सामान्यीकरण है। मुझे लगता है कि यदि किसी वैश्विक लेन-देन को रद्द किया जा रहा है, तो वह किसी घटना को हटाना ठीक है। छद्मकोड पर विचार करें:

try {
    newEvents = processMycommand(myCommand)
    for (Event newEvent : newEvents)
        EventStore.insertEvent(newEvent);
} catch (Exception e) {
    EventStore.rollback();
}

मान लीजिए कि आपका ईवेंट स्टोर एक ट्रांसेक्शनल डेटाबेस है। छद्मकोड में, आप उस स्थिति की कल्पना कर सकते हैं जहां आपने पहली घटना डाली थी, लेकिन जब दूसरी घटना को सम्मिलित करने का प्रयास किया गया तो एक अपवाद फेंक दिया गया था। रोलबैक कमांड स्वाभाविक रूप से पहले ईवेंट के सम्मिलन को वापस कर देगा। क्या यह उचित है?

यदि यह ACID डेटाबेस ट्रांजेक्शन (कमिट / रोलबैक के साथ लेन-देन) के लिए उचित है, तो यह एक क्षतिपूर्ति लेनदेन के लिए उचित क्यों नहीं होगा?

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

अब, यदि क्षतिपूर्ति किसी घटना को हटाने की कोशिश करती है और वह घटना किसी वस्तु पर नवीनतम घटना नहीं है, तो विलोपन नहीं होना चाहिए। लेकिन सामान्य तौर पर, ऐसा होने की संभावना नहीं है, विशेष रूप से पढ़ने में गहन समाधान।


0

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

यहाँ छवि विवरण दर्ज करें रेफरी: https://cambridge-intelligence.com/bringing-time-series-data-to-life-with-keylines/

ऑप्टिकल फाइबर केबल। एक सामान्य साइट से यह कोई फर्क नहीं पड़ता है, लेकिन ये समाधान फेसबुक, गूगल, आदि जैसी विशाल वेबसाइटों के लिए डिज़ाइन किए गए हैं ... इसलिए वास्तव में सवाल का कोई मतलब नहीं है, क्योंकि आप केवल डेटाबेस में एक परिशिष्ट में एक घटना को कैसे हटाएंगे और कैसे आप क्षतिपूर्ति को टाइम मशीन बनाने और किसी घटना को रोकने या बदलने से रोकने के लिए समय में वापस बुलाते हैं ???

AFAIK। इसे हल करने का एकमात्र तरीका एक नया ईवेंट संग्रहण बनाना है जहां आप उन ईवेंट को शामिल नहीं करते हैं जो आप नहीं करना चाहते हैं और इसके बाद पुराने ईवेंट संग्रहण को हटा दें। लेकिन किसी एक घटना को हटाने के लिए यह एक चरम समाधान है। अगर हम GDPR के बारे में बात कर रहे हैं, तो एकमात्र सापेक्ष अच्छा समाधान मुझे पता है कि व्यक्तिगत डेटा को स्टोरेज में एन्क्रिप्ट किया गया है और एक अलग डेटाबेस से एन्क्रिप्शन कुंजी को हटा रहा है।

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