M
M
Mark2019-10-19 06:48:00
Yii
Mark, 2019-10-19 06:48:00

How to solve race condition problem in Yii2 API?

Problem: When sending multiple requests simultaneously to the API method - creating an order, incorrect work occurs: orders are created that are larger than the amount on the balance. Actually the problem is related to "Race Condition".

The main actions of the method

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

Example: the user has a balance of 2200 points. We send requests, and at the moment when the balance becomes zero, the amount of orders exceeds 3400 points.
Questions:
1. How to solve the "race condition" problem in the Yii2 API?
2. Doesn't "PHP session blocking" serve to prevent this behavior? Or is it a violation of REST's "Statelessness" principle and therefore it doesn't appear in the API module?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
L
Lander, 2019-10-19
@usdglander

Use database transactions. In this case, the next request will not receive the balance until it is updated with the previous transaction.

L
LAV45, 2019-10-24
@LAV45

Use `select for update` for your database.
This way you can SELECT block access to the data and safely perform an 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);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question