Pergunta

I'm wandering on DDD and NoSql field actually. I have a doubt now: i need to produce events from the aggregate and i would like to use a NoSql storage. But how can i be sure that events are saved on the storage AND the changes on the aggregate root not having transactions? Does it makes sense? Is there a way to do this without being forced to use event sourcing or a transactional db? Actually i was lookin at implementing a 2 phase commit algorithm but it seems pretty heavy from a performance point of view... Am i approaching the problem the wrong way? Stuffed with questions... Thanks for every suggestion Enrico

PS I'm a newbie on stackoverflow so any suggestion/critic/... is more than welcome Enrico

Edit 1

Well i would need events to notify aggregates that something happened and i they should react to the change. The problem arise when such events are important for the business logic. As far as i understood, after a night of thinking, i can't use a nosql storage to do such things. Let me explain (thinking with loud voice :P):

  • With ES (1st scenery): I save the "diff" of the data. Then i produce an event associated with it. 2 operations.
  • With ES (2nd scenery): I save the "diff" of the data. A process, watch the ES and produce the event. But i'm tied to having only one watcher process to ensure the correct ordering of events.
  • With ES (3d scenery): Idempotent events. The events can be inferred by the state and every reapplication of the event can cause a change on the consumer only once, can have multiple "dequeue" processes, duplicates can't possibly happen. 1 operation, but it introduce heavy limitations on the consumers.
  • In general: I save the aggregate's data. Then i produce an event associated with it. 2 operations.

Now the question becomes wider imho, is it possible to work with domain events and nosql when such domain events are fundamental part of the business process? I think that could be a better option to go relational... even if i would need to add quite a lot of machines to get the same performances.

Edit 2 For the sake of completness, searching for "domain events nosql idempotent" on google: http://svendvanderveken.wordpress.com/2011/08/26/transactional-event-based-nosql-storage/

Foi útil?

Solução

If you need Event Sourcing, you should store events only.

This should be the sequence:

  1. the aggregate root recieves a command
  2. it fires proper events
  3. events are stored

Each aggregate's re-hydratation should be done only by executing events over them. You can create aggregates' snapshots if you measure performance problems on their initialization, but this doesn't require two-phase commits, since you can build snapshots asynchronously via batch.

Note however that you need CQRS and/or Event Sourcing only if your application is heavily concurrent and you need to cope with partition tolerance and compensating actions.

edit
Event Sourcing is alternative to the persistence of object state. You either store the events or the state of the object model. You can save snapshot, but they're just performance tools: your application must be able to work without them. You can consider such snapshots as a caching technique. As an alternative you can persist object state (the classical model), but in that case you don't need to store events.

In my own DDD application, I use observable entities to decouple (via direct events' subscription from the repository) aggregates and their persistence. For example your repository can subscribe each domain events, and execute the actions required by the application (persist to the store, dispatch to a queue and so on...). But as a persistence technique, Event Sourcing is alternative to classical persistence of the observable object state. In most scenarios you don't need both.

edit 2 A final note: if you choose ES, one of the events subscriber can build a relational read-model too.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top