2012-12-11 34 views
10

कभी-कभी मैं सीक्यूआरएस पैटर्न और इवेंट सोर्सिंग का उपयोग कर एक छोटी परियोजना विकसित कर रहा हूं। मेरे पास एक संरचनात्मक मुद्दा है और मुझे पता नहीं है कि इसे हल करने के लिए कौन सा समाधान लेना है।सीक्यूआरएस/इवेंट सोर्सिंग, व्यवसाय नियमों को लागू करने के लिए लगातार डेटा कैसे प्राप्त करें?

निम्नलिखित उदाहरण की कल्पना करें: एक कमांड को जानकारी के साथ भेजा जाता है कि बैंक के एक ग्राहक ने कुछ राशि (जमा कॉमांड) जमा की थी। आदेश हैंडलर/इकाई/कुल (चर्चा के लिए महत्वपूर्ण नहीं है) एक व्यापार नियम लागू किया जाना है; यदि ग्राहक खाते में अधिक पैसे के साथ शीर्ष 10% में से एक है तो कुछ पुरस्कार जीतें।

प्रश्न यह है कि ग्राहक को जमा करने के बाद, अद्यतित, डेटा कैसे प्राप्त कर सकता है, यह जानने के लिए कि ग्राहक अपने जमा के बाद शीर्ष 10% में है या नहीं।

  • मैं घटना की दुकान का उपयोग नहीं कर सकते क्योंकि इस तरह के एक प्रश्न बनाने के लिए संभव नहीं है;
  • मुझे यकीन नहीं है कि मैं पढ़ा मॉडल का उपयोग कर सकता हूं क्योंकि 100% सुनिश्चित नहीं है कि अद्यतित है।

आप ऐसे मामलों में जहां आप डेटाबेस से डेटा की जरूरत है व्यापार नियम लागू करने के लिए कैसे करते हैं? यदि मैं अद्यतित डेटा पर ध्यान नहीं देता हूं तो मैं दो अलग-अलग ग्राहकों को पुरस्कार देने के लिए संभावनाओं में भाग लेता हूं

आपकी राय सुनने के लिए तत्पर हैं।

उत्तर

6

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

मैं यह भी सुझाव दूंगा कि एक समग्र जानकारी को खींचने के लिए कभी भी पढ़ने-मॉडल पर नहीं जाना चाहिए। आप जो हासिल करने की कोशिश कर रहे हैं उसके आधार पर, आप पठन मॉडल (जहां राज्य महत्वपूर्ण नहीं है) से अतिरिक्त विवरण के साथ कमांड को समृद्ध कर सकते हैं, लेकिन कुल खुद को अपने स्वयं के ज्ञात राज्य से खींचना चाहिए।


संपादित

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

आपके मामले में, आपकी गाथा सभी जमा की कुल राशि को ट्रैक कर सकती है, इसलिए जब जमा किया जाता है, तो यह निर्णय लिया जा सकता है कि क्लाइंट अब शीर्ष 10% में है या नहीं। अन्य प्रश्न जो आप खुद से पूछना चाहते हैं ... यदि ग्राहक $ X राशि जमा करता है, और तुरंत $ Y को थ्रेसशोल्ड के नीचे छोड़ने के लिए चौड़ाई देता है; क्या होना चाहिए आदि


बहुत कच्चे तेल की कुल/गाथा संभाल तरीकों ...

public class Client : Aggregate 
{ 
    public void Handle(DepositMoney command) 
    { 
     // What if the account is not known? Has insufficient funds? Is locked? etc... 
     // Track the minimum amount of state required to make whatever choice is required. 
     var account = State.Accounts[command.AccountId]; 

     // Balance here would reflect a point in time, and should not be directly persisted to the read model; 
     // use an atomic update to increment the balance for the read-model in your denormalizer. 
     Raise(new MoneyDeposited { Amount = command.Amount, Balance = account.Balance + command.Amount }); 
    } 

    public void Handle(ElevateClientStatus command) 
    { 
     // you are now a VIP... raise event to update state accordingly... 
    } 
} 

public class TopClientSaga : Saga 
{ 
    public void Handle(MoneyDeposited e) 
    { 
     // Increment the total deposits... sagas need to be thread-safe (i.e., locked while state is changing). 
     State.TotalDeposits += e.Amount; 

     //TODO: Check if client is already a VIP; if yes, nothing needs to happen... 

     // Depositing money itself changes the 10% threshold; what happens to clients that are no longer in the top 10%? 
     if (e.Balance > State.TotalDeposits * 0.10) 
     { 
      // you are a top 10% client... publish some command to do whatever needs to be done. 
      Publish(new ElevateClientStatus { ClientId = e.ClientId, ... }); 
     } 
    } 

    // handle withdrawls, money tranfers etc? 
} 
+1

अपने जवाब के लिए धन्यवाद कैलगरी, आप मेरी बात मिल गया। मुझे सागा पैटर्न के बारे में और अधिक पढ़ना है और फिर मैं एक गठित राय के साथ जवाब देता हूं। –

+0

इसलिए आप इस बात पर चिंतित हैं कि मेरे पास एक गाथा है जिसे एप्लिकेशन के साथ बनाया गया है और डिस्प्ले किया गया है, जैसे सिंगलटन। वह गाथा जमा राशि की कुल राशि ट्रैक करता है। प्रत्येक ग्राहक जो पैसा जमा करता है वह उस राशि को कुल राशि में जोड़ता है। मैं कुल स्टोर को स्टोर करने के लिए इवेंट स्टोर का उपयोग करता हूं? मैं पूछ रहा हूं क्योंकि जब मैं एप्लिकेशन लॉन्च करता हूं तो मुझे वर्तमान कुल राशि लोड करने की आवश्यकता होती है। यह समझ में आता है? धन्यवाद –

+0

@ जेपी - गाथा अपने स्वयं के राज्य का प्रबंधन करेगी। किसी बिंदु पर आप 'शाखा' या 'बैंक' बनाएंगे जो कुल जमा को ट्रैक करने के लिए गाथा शुरू कर सकता है। जब भी जमा या अन्य संबंधित घटना बनाई जाती है, तो गाथा राज्य पुनर्प्राप्त किया जाएगा (आदर्श रूप से स्मृति में कैश किया गया), जैसे कि यह हमेशा चल रहे कुल को जानता है। यदि आपके आवेदन को अन्य कारणों से कुल जानने की आवश्यकता है, तो शायद कुल 'बैंक 'या' शाखा 'कुल राज्य की संपत्ति बन जाती है। आपके समेकित/सागा सभी डेटा पर अधिकार हैं, आप इस प्रकार की जानकारी के लिए रीड-मॉडल पर नहीं जाना चाहते हैं। सही बात? –