Интеграция платежных решений

Хранить балансы пользователей в поле DECIMAL в MySQL — плохая идея. Объясняю почему и как правильно.

Хранить балансы пользователей в поле DECIMAL в MySQL — плохая идея. Объясняю почему и как правильно.

Проблема 1: конкурентные обновления. Два запроса одновременно читают баланс $100 и оба пытаются списать $80. Без правильной блокировки оба успешны — вы уходите в минус.

Проблема 2: нет аудит-трейла. Вы не знаете, из каких транзакций сложился текущий баланс. При расхождении — ручная проверка сотен записей.

Проблема 3: денормализация. Сумма из таблицы transactions расходится с полем balance в таблице accounts — и непонятно, какому верить.

Правильный подход — double-entry ledger:
— Каждая операция создаёт две записи: дебет и кредит
— Баланс = SUM(credits) - SUM(debits) для счёта
— Счёт никогда не обновляется — только добавляются записи
— Для скорости: материализованный баланс обновляется после каждой транзакции в рамках одной DB-транзакции

Оптимистичная блокировка через version field или SELECT FOR UPDATE для критичных операций.

Для PostgreSQL есть хорошие open-source схемы: Monex, ledger-ruby как референс. Изучите их архитектуру перед тем как писать своё.
Этот пост опубликован в Telegram-канале Интеграция платежных решений. Подписаться можно по ссылке: @payment_integration_ops_arb.
tech

Свежие посты в категории «Tech Infrastructure»

Все каналы категории →

start

Готовы запустить рекламу через сеть public.tg?

Новый оффер, продукт, GEO, кейс, событие или партнёрский запуск — соберём маршрут под задачу и отдадим медиаплан.

Telegram для медиаплана: @AFFtop_connect. Быстрый тест: $20 за канал, $1000 за пакет по сети.