CQRS में नया एग्रीगेट रूट कैसे बनाएं?


10

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

मैं AR2 विधि का उपयोग करते हुए AR2 को शुरुआती बिंदु के रूप में बना रहा हूं। अब तक मुझे कुछ विकल्प दिखाई देते हैं:

  1. AR1 में अंदर की विधि createAr2RootOpt1मैं new AR2()डोमेन सेवा का उपयोग करके db imediatelly को इस ऑब्जेक्ट को कॉल और सेव कर सकता है जिसमें रिपॉजिटरी का आरोप है।
  2. मैं पहले एग्रीगेट रूट में घटना का उत्सर्जन कर सकता था। SholdCreateAR2Eventऔर फिर स्टेटलेस सागा है जो इस पर प्रतिक्रिया करता है और कमांड को जारी CreateAR2Commandकरता है जिसे तब संभाला जाता है और वास्तव में AR2 बनाता है और उत्सर्जित करता है AR2CreatedEvent। ईवेंट सोर्सिंग का उपयोग करने के मामले SholdCreateAR2Eventमें इवेंट स्टोर में संरक्षित नहीं किया जाएगा, क्योंकि यह पहले समग्र रूट की स्थिति को प्रभावित नहीं करता है। (या क्या हमें अभी भी इवेंट स्टोर में इसे सहेजना चाहिए?)

    class AR1{
        Integer id;
        DomainService ds;
    
        //OPTION 1
        void createAr2RootOpt1(){
            AR2 ar2 = new AR2();
            ds.saveToRepo(ar2);
        }
    
        //OPTION 2
        void createAr2RootOpt2(){
            publishEvent(new SholdCreateAR2Event());    //we don't need this event. Shoud it still be preserved in event store?
        }
    }
    
    class AR2{
        Integer id;
        Integer ar1Id;
    
        void handle(CreateAR2Command command){
            //init this AR with values and save
            publishEvent(AR2CreatedEvent());    //used for projections afterwards and saved inside AR2 event store
        }
    }
    
    class Saga{
        void handle(SholdCreateAR2Event ev){
            emitCommand(new CreateAR2Command());
        }
    }
    

ऐसा करने का अधिक उचित तरीका कौन सा है?

जवाबों:


2

मुझे लगता है कि विकल्प नं। 2 एक छोटे लेकिन महत्वपूर्ण संशोधन के साथ समाधान है: AR1एक घटना का उत्सर्जन नहीं करना चाहिए जो उद्देश्य बनाना है AR2, इसके बजाय एक AR1WasCreatedघटना का उत्सर्जन करना चाहिए । इस घटना को घटना की दुकान में रखा जाना चाहिए, क्योंकि यह एक महत्वपूर्ण घटना है जो जन्म के समय का है AR1। फिर, एक Sagaके लिए whould listent AR1WasCreatedघटना और बनाने के लिए एक कमांड उत्पन्न AR2: CreateAR2Command

विकल्प नंबर 1 बहुत गलत है। आपको उस तरह की डोमेन सेवा को कभी भी इंजेक्ट नहीं करना चाहिए AggregateAggregatesशुद्ध होना चाहिए, कोई साइड इफेक्ट नहीं है कि घटनाओं की पीढ़ी।

पुनश्च मैं कभी भी रचनाकार से घटनाओं का उत्सर्जन नहीं करता Aggregateक्योंकि किसी वस्तु का एक उदाहरण (प्रोग्रामिंग भाषा अर्थ में) और सृजन (यदि आप चाहते हैं तो जन्म) के बीच एक अंतर है Aggregate। मैं केवल एक handleविधि (जब हैंडलिंग command) से घटनाओं का उत्सर्जन करता हूं ।


आपका क्या मतलब है AR1WasCreated? क्या यह होना चाहिए AR2WasCreated? इसके अलावा, यदि मैं आपके तर्क का उपयोग करता हूं, तो मैं AR2WasCreatedवास्तव में निर्मित होने से पहले घटना का उत्सर्जन करता हूं ? और AR1 के इवेंट लॉग के अंदर इस घटना को सहेजना समस्याग्रस्त लगता है, क्योंकि मुझे वास्तव में AR1 के अंदर इस डेटा की आवश्यकता नहीं है (यह AR1 के अंदर कुछ भी संशोधित नहीं करता है)।
बजे Bojan Vukasovic

ठीक है, 3 साल बाद। यह जाता है AR1WasCreated-> SAGA (नियम है यदि A1 बनाया गया था तो A2 बनाएं) -> CreateAR2Command-> AR2WasCreated
बोजान वुकसोविक

@BojanVukasovic मुझे खुशी है कि मैंने यह काम किया जैसा कि मैंने लिखा :)
कॉन्स्टेंटिन गैलबेनु

2

हमें cqrs वास्तुकला में नई समग्र जड़ें कैसे बनानी चाहिए?

सृजन पैटर्न अजीब हैं

उदी दहन में सामान्य समस्या के बारे में कुछ उपयोगी बातें बताई गई हैं: डोंट क्रिएट एग्रीगेट रूट्स । मूल बिंदु यह है कि कुल मिलाकर कहीं से भी बाहर नहीं निकलता है, और वहाँ डोमेन भाषा है जो वर्णन करती है कि वे कैसे दिखाई देते हैं, जिसे आपके डोमेन मॉडल में कैप्चर किया जाना चाहिए।

जहां यह मुड़ जाता है वह यह है कि आपके डोमेन मॉडल में इकाई जो कमांड को संसाधित कर रही है वह लेनदेन द्वारा संशोधित इकाई नहीं है। यह गलत नहीं है; यह सिर्फ अजीब है (उन मामलों की तुलना में जहां आप किसी इकाई को खुद को संशोधित करने के लिए कहते हैं।

आपका दूसरा तरीका भी ठीक है। "वे घटनाएँ जो हम वास्तव में डेटाबेस को बचाने के बिना बढ़ाते हैं" कभी-कभी "डोमेन ईवेंट" के रूप में संदर्भित होती हैं

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

ध्यान दें: ईवेंट सॉर्वर्ड सिस्टम में, आप आमतौर पर इस तरह से घटनाओं का उपयोग नहीं करते हैं।

इवेंट सोर्सिंग का उपयोग करने के मामले में ShouldCreateAR2Event को इवेंट स्टोर में संरक्षित नहीं किया जाएगा, क्योंकि यह पहले कुल रूट की स्थिति को प्रभावित नहीं करता है।

नोट: घटना के नाम आमतौर पर पिछले काल में होते हैं - ShouldCrateAR2 में गलत वर्तनी है।

हां, यदि आप दूरस्थ कोड को चलाने के लिए सिंक्रोनस बस पर एक घटना फेंक रहे हैं, तो आपको रिकॉर्ड की पुस्तक में उस घटना को नहीं सहेजना चाहिए। यह इस पैमाने पर सिर्फ एक कार्यान्वयन विवरण है।

या क्या हमें अभी भी इवेंट स्टोर में इसे सहेजना चाहिए?

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

इम्पोटोटेंट कमांड हैंडलिंग यहाँ बहुत मदद करता है।


उत्तर के लिए धन्यवाद। एक और बात जो 100% स्पष्ट नहीं है - बाद में अगर मुझे एआर 1 के तर्क के रूप में एआर 2 का उपयोग करना है तो मुझे यह कैसे पास करना चाहिए - चूंकि सीक्यूआरएस कहता है कि एआर का उपयोग केवल लेखन के लिए किया जाना चाहिए और क्वेरी नहीं करना चाहिए। लेकिन मेरे पास कोई अन्य विकल्प नहीं है, AR1.doSmthn(AR2 param)क्योंकि मेरे द्वारा किए गए किसी भी प्रक्षेपण के उपयोग के लिए मेरे पास कोई पूर्ण डेटा नहीं है, जिसकी मुझे आवश्यकता है (केवल AR2 के पास पूर्ण डेटा है)।
बोजान वुकसोविक

> "हाँ, अगर आप रिमोट कोड चलाने के लिए सिंक्रोनस बस पर एक घटना फेंक रहे हैं, तो आपको उस घटना को रिकॉर्ड बुक में नहीं सहेजना चाहिए।" मुझे लगता है कि इसे सहेजने का वास्तविक मूल्य है, जिसमें आप जानते हैं कि कुछ होने के लिए प्रक्रिया को बंद कर दिया गया था, अब आप वास्तव में पूरा होने वाले वाइटर को भी ट्रैक कर सकते हैं। लेकिन मुझे लगता है कि यह प्रयोग के मामले पर निर्भर करता है
Chaosekie
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.