System Design Cases
ACID vs BASE
ACID transactions (Postgres) vs BASE eventual consistency (Cassandra) — две философии в одной топологии. Side-by-side: атомарная транзакция с COMMIT/ROLLBACK против fast-write+eventual-converge. Разъясняет путаницу ACID-C vs CAP-C и spectrum modern БД.
ACID и eventual convergence: не взаимоисключающие лагеря
ACID описывает transaction properties. Atomicity запрещает partial commit, isolation ограничивает наблюдаемые interleavings, durability определяет сохранность подтверждённого commit, а consistency означает сохранение объявленных database invariants. Это не та же буква C, что consistency в CAP.
BASE — не строгий стандарт и не логическое отрицание ACID. Это mnemonic для designs, где доступность и eventual convergence важны в некоторых boundaries. Одна система может держать authoritative transaction в ACID database и строить asynchronous search/feed/cache projection.
Сценарии
Domain mutation и outbox intent входят в один local commit. Ответ command говорит об authoritative source, но не обещает, что asynchronous view уже обновлён.
Constraint violation откатывает domain changes и outbox row вместе. Consistency здесь зависит от правильно заданного invariant; база не угадывает бизнес-правило.
Relay доставляет event at least once, projection применяет stable event id идемпотентно и публикует watermark. Read-your-write требует source read или ожидания watermark, а не слова «eventual».
При broker outage command остаётся durable вместе с outbox, projection lag растёт, relay повторяет publish. End-to-end exactly once не заявляется: correctness даёт idempotent apply.
Почему бинарность ложна
Google Spanner — первичный контрпример утверждению «distributed scale несовместим с сильными transactions»: система глобально распределена, синхронно реплицируется и поддерживает externally consistent transactions. Цена выражается в protocol, latency, clock assumptions и availability under partitions, а не в выборе модного ярлыка.
Amazon Dynamo сделал другой workload-driven trade-off: availability для defined operations, versions, reconciliation и quorum-like settings. Из этого не следует, что каждая NoSQL database имеет одинаковые guarantees.
Требования формулируются наблюдаемо
- balance никогда не уходит ниже нуля;
- duplicate event не меняет итог второй раз;
- read после command видит минимум version V;
- при network partition command fail-open или fail-closed по конкретному invariant;
- stale projection содержит watermark/age;
- recovery восстанавливает source и publication intent.
Связанные темы
Первичные источники
- PostgreSQL isolation: https://www.postgresql.org/docs/current/transaction-iso.html
- Spanner paper: https://research.google/pubs/spanner-googles-globally-distributed-database-2/
- Dynamo paper: https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf
- Apache Kafka design: https://kafka.apache.org/41/design/design/