There are several ways of approaching this. First, the choice of aggregate boundaries must be done with thought. The fact that there are two nouns involved, doesn’t mean there are also 2 aggregates. It may be that User is an entity in the Department Aggregate.
If they really are 2 separate aggregates, you have, again, a few options.
- Use the reservation pattern. This is essentially when Brian describes. First action describes an intent. You then do other actions and confirm the initial intent. This is quite cumbersome, but may give you strong consistency.
- Do a query to validate the intent before deleting the Department. Simply query for any remaining users. If there aren’t any, allow the deletion of the Department, otherwise block it.
- When creating a User, record the identifier with the Department. When deleting a User, remove it from there. When a department is deleted (which is only possible when all users were properly unregistered), User registration will fail and you will be able to compensate by disabling the newly created user account.
Item number 2 may seem “scary” because of the eventual consistency here, but don’t fool yourself. How big is the chance of something like this happening? If it happens, what’s the damage? My point here: don’t waste precious hours on solving an issue that hardly ever occurs and doesn’t cost much to fix when it does.