user1016265
user1016265

Reputation: 2397

DDD: one transaction per aggregate

In the following question there is an answer

In your example, it's pretty trivial: when the customer places an order for 100 items, a domain event is generated and published. Then you have a handler which will check if the order complies with the customer promotions rules and if it does, a command is issued which will have the result of changing the client state to VIP

I think it's clear if Customer is exists, but what if the Customer is going to be created in terms of the same operation (Order submit) ?

Upvotes: 1

Views: 674

Answers (2)

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57387

In your title, you have reversed the rule: "one aggregate per transaction". Which is to say, you change the domain by updating one aggregate at a time.

The update you make, that can be arbitrarily complex.

I think it's clear if Customer is exists, but what if the Customer is going to be created in terms of the same operation (Order submit) ?

So you create the Customer with the VIP property set. It's still one aggregate (Customer), so multiple changes within the handling of a single command are allowed.

That said, everything depends on getting the aggregates modeled correctly. In DDD, the state (VIP flag), the rules that depend on that flag, and the rules that allow you to change that flag; all of these should be part of the same aggregate. So stare at that principle, and discuss the requirements with your domain experts, and explore whether the right model is to set a flag on the Customer aggregate, versus adding a CustomerId to a set in a LoyaltyProgram aggregate.

real case: Order as a guest. In result we should make an order and a customer. 2 AR will be involved. It means Create a customer then pass customerId to Order creation, then create an Order, then need to update Customer flag...

Right - so if this model is correct, there are three commands to be run. Each command writes to a single aggregate. You can use domain events to publish the results of the writes that need to become part of the next command in the chain.

If you want to automate that process, then you replace a human operator issuing commands with a process manager. Basically, the process manager is a state machine; the domain events are triggers, and the asynchronous commands are actions.

Upvotes: 2

ZeissS
ZeissS

Reputation: 12135

Create two events. One for the user being created, one for order itself. I guess code wise you will be calling your createUser routine anyway, which then throws the first event.

Upvotes: 0

Related Questions