Проблема состояния гонки в PHP / MySQL

Я написал bash-скрипт, который пытается отправить некоторые POST-запросы на мой сайт. В моем обработчике запросов POST на сайте у меня есть такая логика:

$std = new \stdClass();
$std->ok = false;
$order = getOrderById(id); // table: orders
$user_id = user_id;
if (!empty($order)) {
if (!orderIsntPerformedByUser($user_id, $order->id)) { // table: performed_orders
updateUserData($user_id, ['user_balance', 'user_balance+1']); // table: users
performOrderByUserId($order->id, $user_id); // table: performed_orders
}
}
echo json_encode((array)$std);
return;

скрипт bash:

for i in {1..5}
do
curl 'http://example.com/handlePostRequest' --form-data="id=1" &
done

Он отправляет 5 запросов в фоновом режиме, и мой сайт мгновенно отвечает. Все запросы выполняются одновременно, и несколько запросов получают «истинный» ответ от сервера.

Я думаю, что мне нужно использовать механизм транзакций, чтобы избежать этой ситуации? Или как сделать некоторую задержку между запросами пользователей, чтобы избежать этого? Какой лучший способ это исправить? Я попытался выполнить это действие для похожих сайтов и получил задержку между запросами.

Большое вам спасибо и извините за мой плохой английский.

2

Решение

Я буду расширять свой комментарий. Вы делаете что-то неправильно на вашем сервере. Вы используете PHP, чтобы проверить, есть ли порядок в базе данных, но PHP-скрипт не является авторитетом данных — MySQL — это. Работа MySQL — заботиться о данных. Ваше требование заключается в том, что вы вставляете в таблицу, и если запись существует с этим order_id — обновить current_balance,

Это достигается путем размещения unique key на order_id, Тогда ваш запрос выглядит так:

INSERT INTO orders (order_id, current_balance) VALUES (1, 13.37) ON DUPLICATE KEY UPDATE current_balance = current_balance + 333.333

Преимущества этого подхода:

  • База данных заботится о данных (это его работа)
  • Проблемы с параллелизмом не возникнут
  • Целостность данных сохраняется
  • У вас меньше кода, чтобы заботиться о
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]