Right tool for right job. There is no single answer/solution to every problem.Many variables to this equation:1. "Size" of application.2. Frequency of change.3. Does it require something more than "just get it working"?4. Do they pay you enough/Can you afford the time to explore all contexts?5. etc:)
1. It does not require 2 phase commit
2. It does not require an ORM
Explained in pseudo code
void HandleCommand(command)
{
// get all the previous events
var events = sql("select * from events where aggregateRootId =
{command.AggregateRootId} and IsPublished = 1");
// create the aggregate root and restore the state by applying the
previous events with some (naming) convention
var aggregateRoot = createAndApplyEvents<SomeAggregateRootType>(events);
// this is the only statement in the command handler that cannot be
moved to some general abstraction for all commands
aggregateRoot.DoSomethingWithTheCommandInAnIdempotentWay(command.Parameter);
// The unhandled events are the events that are not published or stored yet
var unHandledEvents = aggregateRoot.GetUnhandledEvents();
var batchId = Guid.NewGuid();
// add the events to the event store
query("insert into Events IsPublished = 1, BatchId = {batchId},
AggregateRootId = {command.aggregaterootid}, Batch = {
mapToBinaryOrJsonOrWhatever(events)}")
// send the unhandled events to the event handlers
bus.publish(unhandledEvents);
// markt the batch as published
query("update Events set IsPublished = 1 where BatchId = {batchId})
}
This means 3 sql statements are needed for the whole event store and
transactions are not used:
- add batch of events (insert)
- mark batch of events as published (update)
- get events by aggregateroot (select)
Of course, you can add more options to the event store, like replaying
events in different ways or snapshots.
I just reread your first message, but I don't get the point. Maybe you can add some examples.
Unless when you say "using an RDB for write model" you mean a relational data-model and not just using an RDBMS for the Event Store?
The project I'm on at the moment (for a logistics system) is in this exact state, and yes, it does have complexity which would be non-extant if we used event sourcing, particularly so when bi-directional relationships are being maintained (i.e. when child/parent is reversible, and the child can also be the parent.) and having the usual "no, I don't need everything related, I just wanted that small slice of data"
I just reread your first message, but I don't get the point. Maybe you can add some examples.
It's unclear whether you are using an RDBMS as an eventstore or as a
structural datastore. In either case, you are wrong wrt 2PC being
required.
This is not about whether to do
CQRS or not. It's about, when using CQRS, whether to do ES or traditional model.
That said, if you are using CQRS in a part of your system and you are using eventually consistent read models that are populated by events, then I think that event sourcing is NOT gold plating.
Like you mentioned, one of the benefits of using event sourcing when applying CQRS in a BC is that I can focus on designing my events and commands and I don't have to worry about designing a relational model on top of that that's just going to change when my requirements change. I just don't want to deal with the headache an ORM is going to bring.
One complexity when using event sourcing is the amount of events that are stored over time.
Hope I didn't just go on a crazy man rant,
You are assuming "save events" and "publish events" happen in the same
tx. Split it up. 2 txs.
However, despite the podcast's misleading title, the entire last half of the podcast is mostly about when to use event sourcing if you've decided to use CQRS.
I still assert that you should listen to it. It's very good material.
However, despite the podcast's misleading title, the entire last half of the podcast is mostly about when to use event sourcing if you've decided to use CQRS.
I still assert that you should listen to it. It's very good material.
So to rephrase: It appears to me that using a traditional data model (in an RDB environment) for the write side brings about complexity that doesn't appear to exist when using event sourcing, which seems to be the opposite of what is normally argued, namely that event sourcing should only be used if needed, competitive advantage, etc.
You just moved the queue to the database so you can do a local transaction instead of 2PC :)
If you find 2PC between a relational database and a messaging framework you can the the following.1) Make you relational model2) Instead of publishing the event on save, write the event in some separate table in the same transactions. Such table would of course reside in the same database where the model resides.3) Provided trigger are supported by you RDBMS, we can use a trigger to publish the event and so on (AFTER). We eliminate some latency that might be created by the communication between your system and some messaging component. That is all. So you don't necessarily need 2PC.
You just moved the queue to the database so you can do a local transaction instead of 2PC :)
Indeed, but now I'm persisting the events into a data store anyway, which seems to me to be the worst possible solution, i.e. doing both event storage AND relational domain model maintenance.
Hi,Indeed, but now I'm persisting the events into a data store anyway, which seems to me to be the worst possible solution, i.e. doing both event storage AND relational domain model maintenance.
I took that you wanted to maintain your relational database model and still use CQRS while avoiding 2PC. So I gave you a solution.
Do you usually work in green field projects with the power to choose any technical component?
My experience is that green field projects compared with brown field projects are relatively rare. I usually work on brown-field lately. This might be what you just need for those occasions were you need to avoid 2PC and retain some control on your side of the equation. Just a thought.
PS: I think a lot of assessments made over CQRS are relatively naive for brown field projects considering todays corporate landscape. But I may be wrong. Sometimes the best solution is one that people can understand in 5 minutes.
Yes, DDD + CQRS and particularly ES does require some outside-box thinking, so it very much is environment dependent.
So in summary, IF you want to do TDD, am I the only one that thinks ES
along with CQRS is not goldplating, and in fact it makes the code that
uses CQRS much much easier to implement, and enables behavioral unit
testing?
-Julian