2012-12-11 29 views
10

đôi khi tôi đang phát triển một dự án nhỏ sử dụng mẫu CQRS và Sourcing Event. Tôi có vấn đề về cấu trúc và tôi không biết phải giải quyết giải pháp nào.CQRS/Event Sourcing, cách lấy dữ liệu nhất quán để áp dụng quy tắc kinh doanh?

Hãy tưởng tượng ví dụ sau: Lệnh được gửi kèm theo thông tin rằng khách hàng của ngân hàng đã gửi một số tiền (DepositCommand). Trong trình xử lý lệnh/Thực thể/Tổng hợp (không quan trọng đối với cuộc thảo luận), quy tắc kinh doanh phải được áp dụng; Nếu khách hàng là một trong 10% hàng đầu có nhiều tiền hơn trong tài khoản, hãy giành một số giải thưởng.

Câu hỏi đặt ra là làm thế nào tôi có thể cập nhật, thống nhất, dữ liệu để biết liệu khách hàng sau khi tiền gửi của họ có nằm trong top 10% hay không.

  • Tôi không thể sử dụng cửa hàng sự kiện vì không thể thực hiện truy vấn như vậy;
  • Tôi không chắc liệu tôi có thể sử dụng mô hình đã đọc vì không phải là 100% chắc chắn đã được cập nhật.

Bạn làm cách nào, trong trường hợp bạn cần dữ liệu từ cơ sở dữ liệu để áp dụng quy tắc kinh doanh? Nếu tôi không chú ý đến dữ liệu cập nhật, tôi chạy vào các khả năng của giải thưởng cho hai khách hàng khác nhau

Mong muốn được nghe ý kiến ​​của bạn.

Trả lời

6

Mọi thông tin mà tổng hợp yêu cầu đưa ra quyết định kinh doanh phải được lưu trữ như một phần của trạng thái tổng hợp. Như vậy, khi một lệnh được nhận để gửi tiền vào tài khoản của khách hàng, bạn đã có trạng thái hiện tại/cập nhật cho khách hàng đó có thể chứa số dư hiện tại cho mỗi tài khoản của họ.

Tôi cũng khuyên rằng tổng hợp không bao giờ nên đi đến mô hình đọc để lấy thông tin. Tùy thuộc vào những gì bạn đang cố gắng đạt được, bạn có thể làm phong phú thêm lệnh với các chi tiết bổ sung từ mô hình đã đọc (trạng thái không quan trọng), nhưng bản thân tổng hợp sẽ được kéo từ trạng thái đã biết của chính nó.


EDIT

Sau khi đọc câu hỏi, tôi nhận ra bạn đang nói về việc theo dõi tình trạng trên nhiều uẩn. Điều này rơi vào cõi của một câu chuyện. Bạn có thể tạo một saga theo dõi ngưỡng được yêu cầu nằm trong top 10%. Vì vậy, bất cứ khi nào một khách hàng thực hiện một khoản tiền gửi, các saga có thể theo dõi nơi này đặt chúng trong bảng xếp hạng. Nếu khách hàng đó vượt qua luồng, bạn có thể xuất bản lệnh từ saga để cho biết rằng họ đáp ứng các tiêu chí bắt buộc.

Trong trường hợp của bạn, saga của bạn có thể theo dõi tổng số tiền gửi để khi gửi tiền, có thể quyết định xem khách hàng hiện có nằm trong top 10% hay không. Các câu hỏi khác bạn có thể muốn tự hỏi mình ... nếu khách hàng gửi số tiền X $, và ngay lập tức widthrawls $ Y để giảm trở lại dưới sự xôn xao; chuyện gì sẽ xảy ra? Vv


tổng Rất thô/saga xử lý các phương pháp ...

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

Cảm ơn bạn đã trả lời của bạn Calgary, bạn có quan điểm của tôi. Tôi phải đọc thêm về mẫu Saga và sau đó tôi trả lời với một ý kiến ​​được hình thành. –

+0

vì vậy bạn đang sugesting rằng tôi có một saga được tạo ra và xử lý với các ứng dụng, giống như một singleton. rằng saga theo dõi tổng số tiền gửi của tiền gửi. mỗi khách hàng gửi tiền thêm số tiền đó vào tổng số tiền thưởng. để lưu trữ tổng số tiền tôi sử dụng cửa hàng sự kiện? tôi hỏi vì khi tôi khởi chạy ứng dụng tôi cần tải tổng số tiền hiện tại. Điều này thật ý nghĩa? cảm ơn –

+0

@JP - Saga sẽ quản lý trạng thái riêng của nó. Tại một thời điểm nào đó, bạn sẽ tạo một 'Chi nhánh' hoặc một' Ngân hàng' có thể bắt đầu câu chuyện để theo dõi tổng số tiền gửi. Bất cứ khi nào một khoản tiền gửi hoặc sự kiện liên quan khác được thực hiện, trạng thái saga sẽ được lấy ra (lý tưởng được lưu trữ trong bộ nhớ), sao cho nó luôn biết tổng số đang chạy. Nếu ứng dụng của bạn cần biết tổng số vì các lý do khác, thì có lẽ tổng số sẽ trở thành thuộc tính của trạng thái tổng hợp 'bank' hoặc' branch'. Tổng hợp/sagas của bạn là quyền hạn trên tất cả dữ liệu, bạn không muốn đi đến mô hình đọc cho loại thông tin này. Có lý? –

Các vấn đề liên quan