Баланс в MySQL — это не архитектура, а будущая причина двойных списаний
Ledger-система не должна хранить «текущий баланс как истину». Истина — это журнал проводок: debit/credit, статус, ссылка на операцию, идемпотентный ключ. Баланс — производная, которую можно пересчитать. Если вы пишете деньги прямо в одну строку MySQL, вы сами приглашаете гонки, фантомные остатки и вечный спор с поддержкой: «у нас всё сходится, кроме клиента».
Нормальная схема живёт на трёх костылях, но честно:
— immutable ledger: запись не редактируется, только новая корректирующая проводка;
— read model: отдельная таблица для быстрого чтения баланса;
— reconciliation: сверка между журналом, процессингом и сеттлментом.
Идемпотентность или смерть. Без неё retry превращается в дубль, а дубль — в инцидент.
MySQL тут не враг. Враг — попытка использовать её как бухгалтерскую книгу и cache одновременно. Хотите atomicity? Делайте проводки в одной транзакции. Хотите масштабирование? Читайте из проекции, а не из live-агрегата. Хотите аудит? Храните неизменяемую историю, а не «update balance set amount = amount + 1».
Если у вас в базе есть только поле balance и надежда на optimistic locking — поздравляю, у вас не ledger, а лотерея. Документация — это ложь, логи — истина. Начинайте с журнала событий, а не с цифры на витрине.
Интеграция платежных решений
@payment_integration_ops_arb
Баланс в MySQL — это не архитектура, а будущая причина двойных списаний
Этот пост опубликован в Telegram-канале Интеграция платежных решений. Подписаться можно по ссылке: @payment_integration_ops_arb.