Event Sourcing and Post/Pre Dated Transactions

There was a recent question on the dddcqrs list asking about retroactive events as well as post-dated events. This is quite a common question and the answer is YES. Event Sourcing works very well on these types of systems. In this post we will look at how such systems tend to be built.

It is possible to allow the back/future dating of any transaction relatively easily. It could be hard coded in the handling of any event. In general however you would not want to hard code such behaviours for every event that could be pre/post dated. Instead in such systems you will generally come up with mechanism that applies to any event.

One such way of doing this would be to add metadata to the event (either on the event itself or to an envelope/metadata describing the event). An example of this could be:

{
     applies : "2011-10-10T14:48:00"
}

This also applies to a similar pattern

{
     reverses : 1764532
}

Where the event is said to be a reversal of a previous event.

This would say that the event should be treated as if it were put there on Oct 10 2010. While being a very simple framework this is also a very common mechanism. If you look in the accounting domain this is regularly done. I can put something onto my books today but apply it to some point in the past (or in the future). The record is still known to have been put today but can apply to another time period. This is commonly done around year end where things need to be applied retroactively to the previous period.

This leads to some interesting differences in how queries operate. It introduces two forms of every query in the system “As of” vs “As At”. From BizWritinTip

BizWritingTip response: This is quite an interesting point. Most people are accustomed to using “as of.” However, when providing a snapshot of a particular position on a certain date, “as at” is the correct term. You will find it often in accounting.

“As at” means as it is at that particular time only. It implies there may be changes.

Example

As at 9 a.m. today, 30 people were registered for the event.

“As of” means as it was or will be on and after that date.

In other words an “As at” query will give us results at a particular time point within the stream (what did we know as at this point in time). This query operates in the same way as a query in any normal event based system, you replay events up until that point in time. Using the accounting system example for a query as at 2010/10/10 you would query all transactions up to that point in time.

The second query type “As of” also takes into consideration events that may need to be retroactively applied. In this query you would replay the event stream up to the point in time that was specified. You would look through the rest of the stream for any events that would need to be applied retroactively before the time specified in the query and apply those as well. This can obviously be an expensive query if you have a large stream. Using the accounting example you can imagine doing the equivalent of the “as at” query and then applying any events in the rest of the stream that have an applies that is before the date of your query.

It is common when dealing with large streams that contain very few retroactive events to build up an index in a separate stream of retroactive events to avoid having to look at a large number of events. Imagine in the accounting example having 25k transactions of which 5 were retroactively applied. You don’t want to have to scan all 25k just to get the five.

As you can see both of these types of queries are relatively simple conceptually. This however leaves one other time based query to deal with and that is the concept of post dating. In this case as at might ignore the postdated event if the applies is after the time point that the query is being executed for.

Overall Event Sourcing works as a relatively simple model for these types of queries and has been used for centuries to provide for the exact behaviours desired in the question.

2 Comments

  1. Eric Davis
    Posted September 16, 2016 at 2:15 pm | Permalink | Reply

    Interesting concept and approach. I understand how this would work when querying the event store and re-hydrating the domain model for a particular effective date by filtering out events that weren’t to be applied before that date. But how would this concept work with your read model projections? If I apply a command that doesn’t take effect until some time in the future, what should happen with my current state read model? And once that future date for the command comes and goes, how would the current state read model get updated?

    • Posted November 6, 2016 at 11:24 pm | Permalink | Reply

      You support multiple views for reading (reordered vs non-reordered)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: