Skip to content

Improvements to avoid out-of-order events / lost events in sos-restful #14

@stefanocke

Description

@stefanocke

Hello Oliver,
at first, thanks a lot for the comprehensive example and for your efforts to bring more support for DDD into Spring (Data).
I have a suggestion for some minor improvements of sos-restful regarding event timestamps: Currently the timestamp is set in the constructor for the event. In case a transaction takes a bit longer than another one, it might happen that an event with an "earlier" timestamp is seen later by other transactions. That is, we get out-of-order events. Even worse, if a consumer polls between the commit of the first and the second transaction, it might miss the out-of-order event at all, since it has already stored the later timestamp in its database and will never query for "earlier" events again.
To solve this problem, we would need to store the "timestamp of the transaction commit" in the event. However... there is no such thing in JPA (or even in SQL) at all.
But I think, with some simple changes, we can get very close to that:

  • PersistingEventListener could be @TransactionalEventListener with phase "BEFORE_COMMIT", to get as close as possible to the commit
  • PersistingEventListener should perform a flush before persisting the event(s) to make sure most of the SQL work is done before. Again this is to get as close as possible to the commit.
  • Instead of a timestamp, a database sequence should be used. JVM time can be different on each node and even database time might not be reliable (see comment below)
  • The flush in combination with @TransactionalEventListener will make sure that Hibernate does not rearrange the SQL Statements in a way where the sequence number is retrieved before the insert statement(s) for the aggregate are executed. Instead it will be retrieved as close to the commit as possible. Since the aggreagte is locked in the database by the insert statement, there is no danger that some "faster" transaction will commit an event (with a higher sequence number) for the same aggregate meanwhile.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions