Вопрос проверяет умение защищаться от гонок данных и некорректных проверок в конкурентной среде.
Проверка баланса должна выполняться внутри транзакции, а не в коде приложения. Иначе два параллельных запроса могут пройти проверку одновременно. Обычно используют блокировки строк или атомарные SQL-операции. Это гарантирует, что баланс не уйдёт в минус.
Проверка вида if balance >= amount вне транзакции небезопасна.
Перед выбором подхода важно учитывать уровень конкуренции.
Блокировка строки
SELECT ... FOR UPDATE
защита от параллельных изменений
Атомарный UPDATE
обновление только при достаточном балансе
проверка и списание в одном запросе
Проверка результата операции
анализ количества затронутых строк
откат при неуспехе
UPDATE users
SET balance = balance - 100
WHERE id = :user_id AND balance >= 100;
Если обновлено 0 строк — средств недостаточно.
Защита от перерасхода баланса должна быть реализована на уровне базы данных, а не только в бизнес-логике.