Grmice
Grmice

Reputation: 31

Race condition issue in PHP/MySQL

I wrote a bash script that tries to send some POST requests to my website. In my POST request handler on the website I have a logic like:

$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 script:

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

It sends 5 post requests in the background and my website responses instantly. All requests execute at the same time and a few of the requests receive "true" response from the server.

I think that I need to use transaction mechanism to avoid this situation? Or how to do some delay between user requests for avoid it? What's best way to fix it? I tried to do this action for similar websites and I got delay between a requests.

Thanks you so much and sorry for my bad English.

Upvotes: 3

Views: 2270

Answers (1)

N.B.
N.B.

Reputation: 14061

I'll expand on my comment. You're doing things wrong on your server. You're using PHP to validate whether the order is in the database, but the PHP script is not the data authority - MySQL is. MySQL's job is to take care of data. Your requirement is that you insert into the table, and if the record exists with that order_id - update the current_balance.

This is achieved by placing a unique key on order_id. Then your query looks like this:

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

Benefits of this approach:

  • Database takes care of the data (that's its job)
  • Concurrency problems won't occur
  • Data integrity is preserved
  • You have less code to take care of

Upvotes: 4

Related Questions