Agent Wranglers

ARC-76Recommended

Change one aggregate per transaction

Save one aggregate per database transaction. Refer to other aggregates by their ID, and update them afterwards through events.

How to do it

A transaction that changes an order, a customer and the stock at once locks all three, and two such transactions deadlock or block each other. When one aggregate holds another as an object, code changes both without noticing. Hold a CustomerId, not a Customer. When placing an order must reduce stock, save the order with an event in an outbox, as Send side effects through an outbox says. The stock handler then changes the stock in its own transaction. Inside one aggregate, follow Wrap multi-step changes in a transaction.

How to check

No aggregate type has a field whose type is another aggregate's root, which the type checker or an ArchUnit rule can test. Each repository's save method writes the tables of one aggregate only.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/architecture/domain-model/one-aggregate-per-transaction">Agent Wranglers clean code and architecture playbook</a>. In code you write, add a comment next to it with the same link.