Skip to main content

Save conflicts and cross-context intermediate states

What This Concept Is​

The aggregate transition and its persistence protocol jointly protect an invariant. Cross-context coordination adds a separate state machine for partial progress. These are distinct mechanisms: a correct local transition cannot promise an atomic business outcome across independent contexts.

Why It Matters Here​

The reference lab is deliberately single-writer and in-memory. The original aggregate lab must extend it with a repository and an asynchronous workflow rather than treating passing pure-function tests as sufficient evidence for a service.

Concrete Example​

Writers A and B both load an empty capacity-3 pool at revision 7. Each locally reserves 2 and passes the invariant. A saves revision 8. B must not overwrite that state or append its result unchecked. A compare-and-save protocol rejects B's expected revision 7; B reloads revision 8 and re-evaluates, now refusing the additional 2. Retrying only the stale save is insufficient.

Next consider a workflow with reservation held, payment pending, payment confirmed and release pending states. Payment timeout leaves uncertainty; do not label it declined. A late payment confirmation after a cancellation request needs an explicit policy such as refund/reconciliation. Compensation is a new business action and may fail; it is not a rollback that erases history.

Common Confusion / Misconception​

A database transaction around one save does not automatically prevent a stale read-modify-write. A separate context's mutable state does not become part of this aggregate merely by storing a copy. Domain events describe accepted changes; integration messages need publication and retry semantics, such as the outbox/inbox mechanisms already studied.

How To Use It​

Implement an expected-version repository contract in the original service lab. Force two readers to share a revision, allow one save and require the other to conflict. Re-run the command after reload. Keep the capacity check and save atomic under the selected repository mechanism. Then draw and execute an asynchronous reservation/payment trace with duplication, reordering and an unavailable participant.

Check Yourself​

Why must conflict retry include re-evaluation? Which fact is known after a timeout? Can a compensating release fail? What retained evidence prevents an old command from reviving a released reservation?

Mini Drill or Application​

Preserve a concurrent lost-update counterexample and its repaired trace. Model a payment confirmation arriving after cancellation and defend the resulting state. List the operations requiring human reconciliation. Connect context ownership, invariant scope, message identity and recovery behavior on one diagram.

Read This Only If Stuck​

Learning Domain-Driven Design — application services and integration. Reuse Semester 06 transaction/outbox evidence rather than claiming the pure domain lab implements durable messaging or concurrent persistence.