Атомарное условное списание баланса в PostgreSQL

Более зрелый вариант — атомарное условное списание в PostgreSQL с проверкой результата. Оно защищает общий баланс между процессами и экземплярами приложения, а не только внутри одного event loop.

Короткий ответ

Что ответить на собеседовании

Более зрелый вариант — атомарное условное списание в PostgreSQL с проверкой результата. Оно защищает общий баланс между процессами и экземплярами приложения, а не только внутри одного event loop.

Подробный разбор

Ответ с пояснениями

Условие

Практическое задание
Две корутины читают баланс 100, каждая списывает 80 и между чтением и записью есть await. Какое решение более зрелое?

  • Логировать отрицательный баланс после списания.
  • Использовать блокировку для критической секции и добавить конкурентный тест.
  • Сделать списание атомарным в PostgreSQL и проверить результат операции.
  • Ничего не менять: AsyncIO однопоточный.
  • Убрать await из обработчика.
  • Проверять баланс повторно перед записью.

Ответ

Более зрелый вариант — атомарное условное списание в PostgreSQL с проверкой результата. Оно защищает общий баланс между процессами и экземплярами приложения, а не только внутри одного event loop.

Например:

UPDATE accounts
SET balance = balance - 80
WHERE id = :id AND balance >= 80
RETURNING balance;

Из двух конкурентных списаний с баланса 100 успешно пройдёт одно; отсутствие строки результата означает отказ по условию или отсутствие счёта. Для настоящего платежа добавляют транзакционный журнал и уникальный ключ операции. Локальный lock и конкурентный тест полезны, но не защищают другие процессы. Проверка после записи или повторное чтение без атомарности гонку не устраняют.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее