Search code examples
javamicroservicesevent-sourcing

Handle Status Update In Even Sourcing Pattern


I was looking at an auditing pattern to save history of my entity and I came across Event Sourcing Pattern. It is an interesting pattern and most of it makes sense to me but I had one question on how to implement a certain use case scenario?

Use Case:

  1. There is an invoice generated with amount of $100 and status as in review.
  2. Then the invoice status is updated to billed
  3. Then a payment of $50 is adjustment of $20 is made and status is updated to paid
  4. We later realized that the amounts were incorrect. So we want to rollback previous transaction and revert bill status to billed again
  5. We then post a payment of $70 and adjustment of $20 and update invoice status to complete.

From my understanding of event store. It should only contain the actions that were applied on the entity.So the event always has the updated transaction amounts(payment and adjustment) and status.

Database:

Invoice:

| id    | balance | payment | adjustment | status   |
|-------|---------|---------|------------|----------|
| 12345 | 10      | 70      | 20         | Paid     |

Event Store:

| event_id | invoice_id | Event            | Payload |
|----------|------------|------------------|---------|
| 1        | 12345      | Invoice_InReview | JSON    |
| 2        | 12345      | Invoice_Billed   | JSON    |
| 3        | 12345      | Invoice_Paid     | JSON    |
| 4        | 12345      | Invoice_Reversed | JSON    |
| 5        | 12345      | Invoice_Paid     | JSON    |

JSON contains info about changes to payment,adjustment and status

So here are my questions

  1. I get how balances can be reversed but I do not see how we can accomplish the same effect for status
  2. Also how will I handle if api calls(commands) come out of order for the above events. i.e
    • Step 3 calls service
    • then step 5
    • then step 4.

from what I understand the balances will be fine but the invoice status will be incorrect.

Please advise me on how to best handle this on event sourcing pattern.


Solution

  • I get how balances can be reversed but I do not see how we can accomplish the same effect for status

    So the first thing to do would be to check with your domain experts to understand if the ubiquitous language has the concept of the status of an invoice between the reversal and the repayment.

    Based on what I see here, I would expect a reversal by itself to put the status on billed again. We thought it was paid, but that entry is a mistake, so we would restore the object to its previous state.

    If that were correct, then we would have a status of Billed there.

    But it might not be -- this isn't an undo, it's a behavior within your domain. It might be that this moves the domain to a previously undiscovered part of the state machine.

    how will I handle if api calls(commands) come out of order for the above events.

    There are two different questions that may be hidden there - I will summarize each.

    If you are worried about downstream consumers reacting to events, it is important to design your consumers such that -- if they need to know the entire history, then they read from the history. A consumer that reacts to the changes in history will read an ordered history from the event store, rather than reacting to messages that appear on message transport. In other words, the published event acts like a notification, telling the consumer to refresh its copy of the history.

    If you are worried about the fact that you get the "wrong" history if commands appear out of order, then you need to review and integrate Udi Dahan's essay Race Conditions Don't Exist

    A microsecond difference in timing shouldn’t make a difference to core business behaviors.