0

If there are 2 bounded contexts: Spending and Account management, how to prevent so the user doesn't spend more than he has in balance?

I understand the case when we have Order > Payment > Shipment sequence for a single product, but here it's more like Order > Balance Check > Shipment and i don't understand how to check the balance in other bounded context and be sure user would never spend more than he has.

Is this situation even possible to solve with eventual consistency? I would prefer it with eventual consistency. If not, is the safe option to keep balance within the Spending bounded context?

[UPDATE] I haven't mentioned, I'm thinking about the solution in event driven architecture where bounded contexts exchange information through events only.

dee zg
  • 13,793
  • 10
  • 42
  • 82

1 Answers1

2

In your case, eventual consistency for a balance check is not suitable.

Requirement: Do not ship goods until we know customer can pay.

Therefore you have a firm business requirement that the shipment process must wait for a response from the account balance check process. If balance check service is down then shipment cannot proceed.

In other business scenarios you may be able to continue with one part of the process and let the other part work on eventual consistency with an out-of-process message delivery in between the services. In your case, you cannot do this for the check balance part of the process.

To further complicate, your process would be:

Order > Check Balance > Ship > Deduct Funds.

You don't want to deduct the funds until shipment has occurred in case there is failure in shipment for some reason, but you definitely don't want to ship before the balance has been checked.

For this, I'd introduce the concept of an 'earmark' or 'reserved funds'.

So, your "Spending" context will send a 'reserve funds' request to "Account Manager" context and wait for response. That response can include a correlation id of the 'reservation of funds'. Your Account Management service would need to understand the concepts of "actual balance" and "reserved funds" to calculate an "available balance".

Once your shipment has completed you can then send a 'confirmation' to account management quoting the correlation id, so that account management can adjust "actual balance" and delete the "reserved funds". That step, in my opinion, could work with eventual consistency.

Neil W
  • 7,670
  • 3
  • 28
  • 41
  • *Requirement: **Do not ship** goods until we know customer can pay.* - thanks for this sentence in particular! it is an eye opener. so far i was thinking like *do not let customer to order until we know he can pay* but your formulation is much better. and everything else is derived from it naturally. – dee zg Oct 18 '21 at 06:38
  • also, i guess you would keep some `Order.Status` field in `Spending` BC that gets updated as other BCs do their things, right? – dee zg Oct 18 '21 at 12:35
  • If you need it to perform your domain logic then, yes. But, don't create one just because you think it might be useful. Create it when you need it. YAGNI is a powerful tool. – Neil W Oct 18 '21 at 12:47
  • well, even if its not for domain logic but for pure UI to keep user informed about what's the status of an order (besides sending emails for each event/step). /btw, these are actually offtopic comments so marking as answer. thanks! – dee zg Oct 18 '21 at 13:13
  • hm hm...actually, i am doing it using CQRS having write & read models separated, but but...where would read model get information about orders current status if its not written anywhere? Or, are you saying there should be some part of the system that compiles the view from different bounded contexts? (order and account management in this particular case) – dee zg Oct 18 '21 at 13:20
  • 1
    I deleted my last comment after reading it back to myself. Maintaining the status for a feed to the read model is fine. Sorry for confusion. – Neil W Oct 18 '21 at 13:21
  • i'm glad we've sorted it out as i started to doubt very fundamentals i've learned on CQRS :). thank you for going an extra mile on this question. really appreciate it! – dee zg Oct 18 '21 at 13:23