Eventual consistency permits related data to disagree temporarily while updates propagate toward a consistent state. It is a pragmatic option when enforcing one aggregate boundary would create excessive maintenance cost. section 3.5.1 section 6.2.2
Consider eventual consistency when deciding whether to split aggregates:
- Keep the aggregate intact when an invariant must always be current and the maintenance cost remains acceptable. section 3.5.1
- Split the aggregates when no real invariant crosses the boundary, or accept delayed synchronization when the benefit clearly outweighs immediate consistency. section 3.5.1
- Use domain events to notify one aggregate about changes made in another. section 3.5.1
Cancelling an enrollment
When cancelling an enrollment, available spots can be updated through domain-event listeners rather than synchronously inside both aggregates. The count may briefly lag, but users may accept that tradeoff. A SQL query can instead calculate the current count, optionally with caching. section 6.2.2
Listing 6.3 The cancel method in the Offering entity
class Offering {
private List<Enrollment> enrollments;
private int availableSpots;
// ...
public void cancel(Employee employee) { #1
Enrollment enrollmentToCancel = findEnrollmentOf(employee);
if(enrollmentToCancel == null)
throw new EmployeeNotEnrolledException();
Calendar now = Calendar.getInstance();
enrollmentToCancel.cancel(now);
availableSpots++;
}
private Enrollment findEnrollmentOf(Employee employee) { #2
// loops through the list of enrollments and
// finds the one for that employee
// ...
}
}
Inspect the synchronous cancellation design, where cancelling an enrollment immediately increments availableSpots; it provides a contrast with event-driven eventual consistency. section 6.2.2





