Modelling Account transactions with event sourcing.

1,792 views
Skip to first unread message

xiety

unread,
Feb 16, 2016, 7:09:39 AM2/16/16
to DDD/CQRS
One of the reason to use ES is that this is the way how Accounting already works today even without computers.

But if I model AccountTransaction as a separate aggregate, than the transaction itself becomes event sourced.

(I can't do without AccountTransaction aggregate, because Account itself will have too many concurrent changes. And will be loaded too long every time (without snapshotting). And it has no invariant to protect.)

So it happens now that I use ES not for the reason it is used in Accounting. For that reason I use AccountTransaction.

And now I have account audit log (AccountTransaction) with audit log on each of it (Event Sourcing). It looks quite suspicious.

Am I heading the right direction?

Kijana Woodard

unread,
Feb 16, 2016, 9:33:27 AM2/16/16
to ddd...@googlegroups.com
Please describe your accounts.
I've modeled Account and it works well. Accounts have invoices, payments, credits, etc...roughly 30 events per year per account. Concurrency is handled in the normal way - optimistically.

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

xiety

unread,
Feb 16, 2016, 9:38:40 AM2/16/16
to DDD/CQRS
I'm talking about Ledger Accounts. Average 100 transactions per day per account.

Kijana Woodard

unread,
Feb 16, 2016, 9:57:07 AM2/16/16
to ddd...@googlegroups.com
How are you sure there will be too many concurrent changes?
If there are no invariants, wouldn't you just append the event?

xiety

unread,
Feb 16, 2016, 10:32:33 AM2/16/16
to DDD/CQRS
Yes, I can just append the event.

But I proceeded from
the following assumptions:
1. Model aggregates around invariants.
2. Aggregates are slow to load if they have many events.
3. I don't want to deal with snapshotting, because my domain objects aren't serializable. That's why I choose ES in the first place.

Am I wrong, and snapshot is the only possible way for performant ES?

Greg Young

unread,
Feb 16, 2016, 10:35:47 AM2/16/16
to ddd...@googlegroups.com
If you "have no invariants" on account why would you need snapshots at
all (there is no state to materialize) you would just need a read
model.
Studying for the Turing test

João Bragança

unread,
Feb 16, 2016, 10:37:30 AM2/16/16
to ddd...@googlegroups.com
IMO in an accounting system the real aggregate is the general ledger entry (it must always be in balance) not the 'account.' At this point like greg said your account balance is just a read model.

xiety

unread,
Feb 16, 2016, 1:18:35 PM2/16/16
to DDD/CQRS, joao...@braganca.name
I have a command:
    DebitAccount AccountId = acc-1, Amount = 20.0, Currency = EUR

It arrives to command handler, which then publishes event without using aggregate at all? What stream will this event belongs to, if I make a stream per aggregate type?
    AccountDebited AccountId = acc-1, Amount = 20.0, Currency = EUR, AmountInMainCurrency = 22.27

This events will then be used in another context. So this is write model, I thought.

Or what did you mean by "just a read model"?

Greg Young

unread,
Feb 16, 2016, 1:29:19 PM2/16/16
to ddd...@googlegroups.com, João Bragança
Write event to acount-001234567

If you aren't checking any invariants whats the point of having any
state on the write model?

On the read model you might have something like "account current balances"

Ben Kloosterman

unread,
Feb 16, 2016, 9:28:13 PM2/16/16
to ddd...@googlegroups.com
On Wed, Feb 17, 2016 at 2:32 AM, xiety <xiet...@gmail.com> wrote:
Yes, I can just append the event.

But I proceeded from
the following assumptions:
1. Model aggregates around invariants.
2. Aggregates are slow to load if they have many events.
3. I don't want to deal with snapshotting, because my domain objects aren't serializable. That's why I choose ES in the first place.

Am I wrong, and snapshot is the only possible way for performant ES?


2. Is not really as much as you would think , and if you have a single source of truth identity map actually makes it faster  . 
It is not the aggregation time but the time to fetch the events  and in the typical IPC / DB access latency time you can easily grab a lot of events  ( eg 1000 may take you twice as long as 1) . Most business apps these days are almost completely io bound . 

Most accounting / banking systems have an end of month or end of year roll over , this is the snapshot.  Note this is less so for performance  ( but it helps!) than the fact you want to lock in the past with no further concurrent changes  . Most of the older systems use an exclusive lock type system to do this ( i have no  experience in newer ones .. if it has changed) . 

Ben

xiety

unread,
Feb 17, 2016, 2:34:47 AM2/17/16
to DDD/CQRS
How can I use Identity Map in multi-user environment? When one thread applies a new event to an aggregate, mutating it, another thread calls some method or gets some data from it, or mutates it too, simultaneously. Do I need to introduce locking every method or some actor system, in case of identity map?

Ben Kloosterman

unread,
Feb 17, 2016, 5:35:12 AM2/17/16
to ddd...@googlegroups.com
Yes have a single thread read from a queue.

Most of the time i use CQRS , I use single threaded write domain , sometimes behind a service or multi threaded facade  . Creating / applying events is so fast that a single thread can do millions per second ( see Lmax) . I have had a  project where i  applied logic  single threaded and ensured the entity was loaded before adding the command to the processing queue but its very rare that will be needed.    In most cases trivial multi threaded solutions will be a lot  slower ( locking / contention) than single threaded w identity map and create a lot more problems.  ( queries are often multi threaded though ) .

Also without all the string most or all aggregates in most domains will fit entirely in memory .

Ben 

Aryeh Hoffman

unread,
Mar 24, 2016, 5:22:49 AM3/24/16
to DDD/CQRS
>>> One of the reason to use ES is that this is the way how Accounting already works today even without computers

Can't say I agree with that.  Recorded transactions are at the heart of essentially all systems with the exception of Data Acquisition and Control Systems.  That includes manual systems throughout history.  Human writing came about arguably through the need to record agriculture related transactions.

The recording of all changes is not unique to Event Sourcing, just a feature of it.

Regards, Aryeh

Holger Thiemann

unread,
Mar 26, 2016, 3:03:36 AM3/26/16
to ddd...@googlegroups.com

Hi. To make that clear. "Only a read model" means I have a conceptual Aggregate which has an event Stream but which has no implementation on the write side and is never loaded but the Events are appended from the command Handler directly to the stream? So for all pure crud stuff I do not need any writemodel?

--
Reply all
Reply to author
Forward
0 new messages