@MarkLb

Как решить проблему состояния гонки в API Yii2?

Проблема: При отправке множества запросов одновременно на метод API - создания заказа возникает некорректная работа: создается заказов больше, чем сумма на балансе. Фактически проблема связана с "Состоянием гонки".
Основные действия метода

1. Валидация данных, в том числе баланса.
2. Выполнение коммерческого действия.
3. Создание заказа.
4. Списание баланса.
Обернуто в транзакции.

Пример: у пользователя баланс 2200 поинтов. Шлем запросы, и на момент когда баланс становится нулевым, сумма заказов превышает 3400 поинтов.

Вопросы:
1. Как решить проблему "Состоянии гонки" в API Yii2?
2. Разве "блокировка сессий PHP" не служит для предотвращения такого поведения? Или же это нарушение принципа REST об "Отсутствии состояния" и поэтому она не фигурирует в API модуле?
  • Вопрос задан
  • 252 просмотра
Пригласить эксперта
Ответы на вопрос 2
usdglander
@usdglander
Yipee-ki-yay
Используйте транзакции базы данных. В этом случае следующий запрос не получит баланс, пока он не обновится предыдущей транзакцией.
Ответ написан
@LAV45
Используйте `select for update` для вашей базы данных.
Таким образом вы сможете SELECT-ом заблокировать доступ к данным и спокойно выполнить UPDATE

$sql = Wallet::find()
  ->where(['id' => $id])
  ->createCommand()
  ->getRawSql();

/** @var Wallet $model */
$model = Wallet::findBySql($sql . ' FOR UPDATE')->one();
$model->amount += $amount;
$model->save(false);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы