Enforcing ordering guarantees on database changes

Hello, we have an actor system that accepts events coming in externally, processes them and sometimes makes database changes (CREATE/MUTATE/DELETE). Database changes can only be made as a result of a small set of commands: most of the work involves receiving an event/command, getting relevant data from the database, checking some invariants to see if the commands can be accepted, and “translating” the events/commands into a sequence of the base commands to make database changes.

The issue we are exploring: we’d like to guarantee that if an external event ends up resulting in database changes, those changes should be processed in the order by which the event was received. This is complicated by the fact that we have one session actor per external event/command received by the HTTP server. The naive solution would be for every command/event to receive a number like in the DMV, but then we’d have to let the database know both when (A) the number does not end up resulting in a database change (failed validation/rejected command) or (B) the event ended up lost in actor communications (this one seems harder). I am wondering if there’s a pattern for this already?

Hi @nsadeh,

What you describe is the basis of Event Sourcing, except that you’re swapping the terms.
Have a look at Event Sourcing • Akka Documentation

In a nutshell, commands are sent to the actor and validated. If accepted, they emit events that will then be applied to the state. Akka Persistence will take care of the ordering, persist the events and apply them.

I understand that what gets into your system are originally some external events, but from the point of view of your system, they are commands. So, external events are translated to commands that may or may not change the state of your model.

Have a read on the documentation I linked here. You will need to get familiar with those concepts first and retrofit your system to use Event Sourcing.

As I like to say, one service’s events are implicitly another service’s commands, with the command being “update your worldview to incorporate the event” (and since it’s a command, there’s also an implicit “or just ignore this: your call”

Thanks, that makes a lot of sense! I will be trying this out.