Проблема начинается, когда один бизнес-результат затрагивает несколько сервисов или хранилищ. Заказ создан. Платёж подтверждён. Запас зарезервирован. Уведомление отправлено. Что делать, если третий шаг не состоялся после успешных двух? AMPE использует Transaction & Consistency Design, чтобы заранее определить, где нужна сильная атомарность, где допустима eventual consistency и как система восстанавливает бизнес-инвариант после частичного сбоя.
Начать диагностикуСеть может оборваться.
Участник может зависнуть.
Coordinator — потерять связь.
Lock — держаться дольше ожидаемого.
Технически сильная consistency имеет операционную цену.
Поэтому AMPE сначала проверяет, действительно ли бизнес-инвариант требует синхронной атомарности через границы систем.
Должно быть понятно: какое промежуточное состояние допустимо; сколько оно может длиться; что увидит пользователь; какой процесс завершает согласование; как обнаруживается зависшее состояние.
Eventual consistency — спроектированная модель, а не отсутствие гарантий.
Когда бизнес-операция проходит через несколько сервисов.
Когда локальные транзакции успешны, а общий процесс остаётся частично выполненным.
Когда нужно отказаться от distributed lock или 2PC.
Когда events и база данных должны изменяться согласованно.
Когда retry может повторно выполнить side effect.
Когда система имеет денежные, складские, балансовые или другие жёсткие инварианты.
Когда необходимо объяснить пользователю промежуточное состояние.
Saga разбивает процесс на локальные транзакции и compensating actions.
Но компенсация не всегда является настоящим rollback.
Отменить отправленное письмо невозможно. Вернуть уже обработанный платёж может быть отдельной операцией. Освободить резерв спустя время может иметь новые последствия.
Поэтому AMPE проектирует семантику компенсации на уровне бизнеса.
Если сервис сначала пишет в БД, потом публикует event, между этими действиями возможен сбой.
Transactional outbox позволяет зафиксировать изменение состояния и намерение отправить событие в одной локальной транзакции.
Это не универсальная архитектура, а сильный паттерн для согласования database state и messaging.
«Баланс не может стать отрицательным». «Один серийный номер не может быть отгружен дважды». «Резерв не может превышать доступное количество».
Сначала фиксируется инвариант.
Только потом выбирается locking, optimistic concurrency, serialization, reservation, saga или другой механизм.
Профиль клиента может обновиться через секунду.
Баланс — требовать read-after-write consistency.
Аналитическая копия — отставать на минуты.
AMPE не навязывает один уровень согласованности всему продукту.
Бизнес-инвариант определяет требования.
Граница данных — локальную transaction boundary. Распределённый процесс — допустимые промежуточные состояния. Failure model — retry, compensation и recovery. Observability — способность находить незавершённые операции.
Так consistency проектируется исходя из смысла результата.
Частичные сбои получают предусмотренное поведение.
Eventual consistency становится понятной пользователю и эксплуатации.
Повторные операции не нарушают инварианты.
Транзакционные границы становятся меньше и яснее.
Система легче восстанавливается после сетевых и сервисных отказов.
И главное — согласованность выбирается осознанно, а не как случайный побочный эффект распределённой архитектуры.
Первый шаг
Для начала достаточно описать бизнес-операции, которые сегодня затрагивают несколько систем и особенно болезненно переживают частичный сбой. Диагностика покажет, какие инварианты действительно требуют сильной consistency и где можно упростить модель.