Rebuilding a read model updated from more than one aggregate root

1,247 views
Skip to first unread message

Andrew Easter

unread,
Oct 16, 2013, 7:07:31 PM10/16/13
to ddd...@googlegroups.com
I've tried to search this mailing list but can't find a definitive answer - maybe there is no definitive answer!

If I have a read model that projects events from multiple aggregate roots, the obvious thing that springs to mind is ensuring, when rebuilding the read model from scratch, that events are replayed in precise order. Now, this is fine for a particular aggregate root but not okay across multiple aggregate roots in the absence of globally unique sequence numbers (something I reckon is best to avoid if at all possible). 

My gut is telling me that, in practice, it's unlikely to be a problem - i.e. in many cases, it probably doesn't matter if events are not received in precise order, the outcome will still be the same. However, are there any other strategies people have come across - without using global sequence numbers - to ensure correct ordering?

Even without caring about precise order across separate aggregate root event streams, one is still going to want to get as close as possible. Is it best to use timestamp ordering in that case? It's likely to be an edge case that you have events from separate streams with the same timestamp (assuming millisecond precision).




Tom Janssens

unread,
Oct 17, 2013, 2:09:26 AM10/17/13
to ddd...@googlegroups.com
If it does matter, google for "vector clocks"

Op donderdag 17 oktober 2013 01:07:31 UTC+2 schreef Andrew Easter:

@yreynhout

unread,
Oct 17, 2013, 5:13:51 AM10/17/13
to ddd...@googlegroups.com
Root cause analysis ... why is the order important?

Greg Young

unread,
Oct 17, 2013, 6:41:41 AM10/17/13
to ddd...@googlegroups.com
If you have not partitioned to many servers you should always be able to get a perfect order. Event store as example will give you this assurance
--
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/groups/opt_out.


--
Le doute n'est pas une condition agréable, mais la certitude est absurde.

Sebastian Good

unread,
Oct 17, 2013, 9:02:45 AM10/17/13
to ddd...@googlegroups.com
One classic reason for wanting to get precise order is to write into a relational read model with foreign keys activated. You may find children arriving before parents and other such horrors if you have distributed aggregates, or a read model that has to be flexible if combining data from multiple bounded contexts. Probably easier to relax the constraints and have a tool to check them now and again than it is to try and enforce order on the distributed system producing the events of record.

Andrew Easter

unread,
Oct 17, 2013, 12:18:02 PM10/17/13
to ddd...@googlegroups.com
Thanks for the advice, guys.

As usual, I'm jumping ahead of myself a little bit by asking theoretical questions :-) I haven't actually come across a use case yet where I would need guaranteed order. I'm trying to evangelize DDD/CQRS/ES in my team at work and have plenty of questions being thrown my way - it's nice to be able to provide answers to some of them :-)

Jakub Konecki

unread,
Aug 18, 2015, 7:54:15 AM8/18/15
to DDD/CQRS
Hello,

I would like to hijack this thread ;-) and give an example I've encountered:

I have a Product Catalog which lists Products. Each Product may be delivered by multiple Suppliers, therefore each Product contains a collection of Supplier References which refer to the appropriate Supplier and have a Reference Number that this Supplier assigned to the Product.

 - Supplier A
 - Supplier B
 - Product Catalog
   - Product 1
      - Supplier Reference (Supplier A, ABC123)
      - Supplier Reference (Supplier B, BCD456)
   - Product 2
      - Supplier Reference (Supplier B, BFG876)


I have a read-model projection which generates the list of products:

{
    Name: "Product 1",
    Suppliers: [
        { 
             Name: "Supplier A",
             Reference: "ABC123"
        },
        ......
    ]
}


At the moment the event published by Product Catalog when a new product is added contains the name of the suppliers so the Product projection doesn't have to query Supplier projection nor load Supplier aggregate roots to obtain Supplier Name.

The Product List projection also subscribes to SupplierRenamed event published by Supplier AR and it bulks updates all the products delivered by this Supplier with the new name.

That causes problem with replying all the events: if SupplierRenamed event is processed before ProductAdded than the projection will have the old Supplier name.

Should I add RenameSupplier command to Product Catalog and let it go through the Products and generate SupplierNameChanged events for each Product? I feel the name of the Supplier has nothing to do with the Product Catalog as it doesn't impact any logic there. It's purely a presentation concern. Therefore I think this should be handled by the projection - but how can I write the projection to be invariant on the order of events?

Many thanks for your thoughts,
Jakub

Peter Hageus

unread,
Aug 18, 2015, 7:57:18 AM8/18/15
to ddd...@googlegroups.com
Easiest way is to join product and Supplier at read time, if they’re stored in a relational db.

/Peter

-- 
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.

dypsok

unread,
Nov 10, 2016, 7:10:45 AM11/10/16
to DDD/CQRS
Hi Jakub,
  I know that's an old thread but I am facing the same kind of problems... 
  How have you finally deal with it ?

Dypsok

Alexander Langer

unread,
Nov 10, 2016, 2:37:38 PM11/10/16
to ddd...@googlegroups.com
That's a standard problem. Here are two simple suggestions that you can use
(there are probably more strategies):

a) Enrich the ProductAdded event with all the details of supplier that
you need
at the very moment ProductAdded is published.

This is commonly done with records where you have a somewhat tighter
requirement
on the consistency of multiple related aggregates. For example,
invoices must
retain the original customer addresses even if the customer moves at a
later time.

There are multiple strategies how to enrich the event. You can for
example
listen to the ProductAdded event in a special event handler, query the
supplier
data and put a ProductAddedWithSupplierData event on the bus which is then
used to build the read model.

b) Keep track of *all* the SupplierRenamed events that you have
seen and answer the question "what was the supplier name at time X"
instead of
"what is the supplier's current name"?

On 10/11/2016 13:10, dypsok wrote:
> I know that's an old thread but I am facing the same kind of problems...
> How have you finally deal with it ?

dypsok

unread,
Nov 11, 2016, 6:18:55 PM11/11/16
to DDD/CQRS
Hello,
 For the option B : Where do I have to keep track of the supplierRenamed event ?  
 Just to be clear : I need to have always the current supplier name in my product projection.

 I have followed the option A (ie enriched event) in order to have a denormalized view on query side (ie without any join), but when the supplier name change what I have to do... Like Jakub, I am sure that the supplier name have nothing to do with the product...
 If I recreate my product projection, at final I could have a different name suuplier than the current one ...

Thanks,
 Dyspok
Reply all
Reply to author
Forward
0 new messages