Общий термин для проблемы, которую вы описываете: установить проверку .
Если для бизнеса приемлемо, что инвариант будет нарушаться в течение коротких периодов времени, тогда вы создаете процесс, который отслеживает все ваши клиентские совокупности в поисках конфликтов и уведомляет некоторый процесс исправления, если таковой обнаружен. Вы можете уменьшить (но не устранить) риск коллизий, включив проверку предыдущих записей в свою бизнес-логику; все еще существует вероятность того, что ограничение будет нарушено в гонке данных.
Если это недопустимо (возможно, юридические или финансовые последствия слишком серьезны), тогда все становится сложнее.
Один из ответов, который иногда будет работать, - это взять значения, которые должны быть уникальными, и использовать их для генерации уникального идентификатора для агрегата. К сожалению, имя, фамилия и адрес электронной почты недостаточно стабильны, чтобы быть подходящими кандидатами для такого подхода (что произойдет, если ваш клиент изменит свой адрес электронной почты или свое официальное имя?)
Это оставляет блокировку для всего набора клиентов, когда вы вносите изменения в одного из них. Это может быть так же просто, как заставить любой процесс, который собирается изменить клиента, получить общую блокировку, или поместить всех клиентов в один агрегат, или запрограммировать ограничение в вашем хранилище (подумайте об ограничениях в RDBMS).