Проверяет понимание способов предотвращения двойного списания при параллельных транзакциях, что критично для финансовых и e-commerce систем.
Двойное списание — классическая проблема конкурентного доступа к общему ресурсу, например, банковскому счёту. Если две транзакции одновременно прочитают баланс 100, обе решат, что хватает на списание 80, и обе выполнят UPDATE, баланс уйдёт в минус. Причина — race condition между чтением и записью.
UPDATE accounts
SET balance = balance - 80
WHERE id = 1 AND balance >= 80;
-- если affected rows = 0, средств недостаточно
Здесь проверка и списание происходят в одной атомарной операции, БД сама блокирует строку на время UPDATE. Это устраняет окно между SELECT и UPDATE.
UPDATE accounts
SET balance = balance - 80, version = version + 1
WHERE id = 1 AND version = 5 AND balance >= 80;
-- при конфликте affected rows = 0, повторяем транзакцию
Подходит при низкой конкуренции: не блокирует строки, но требует retry-логики на уровне приложения.
Если клиент может повторить запрос (сеть упала), используйте уникальный idempotency key. Таблица операций с UNIQUE(key) не даст провести списание дважды.
Итог: для финансовых операций комбинируйте атомарный UPDATE с условием, идемпотентные ключи и при высокой нагрузке — очереди. Это гарантирует корректность баланса даже при массовых параллельных запросах.
Уровень
Рейтинг:
5
Сложность:
7
Навыки
Postgres
SQL
Ключевые слова
Подпишись на Node.js Developer в телеграм