Would this WPDB setup result in potential race conditions?


I have a page on my site with numerous elements that can be liked/disliked through a simple admin-ajax call.

In the associated PHP code, it looks like this:

// Fetch the existing meta from this element. The array of users who already voted, and the current score.
global $wpdb;
$row = $wpdb->get_row( "SELECT `rating_users`, `rating_score` FROM `table` WHERE `file_id` = $file_id" );

$voted_users   = $row->rating_users? unserialize( $row->rating_users) : array();
$current_score = $row->rating_score ?: 0;

// Now verify this current user has not already voted, check the array.
foreach ($voted_users as $id => $ip)
    // check if current user ID / IP has voted, exit if true...

// Good to go, add this user to the list of users who have voted now.
$voted_users[] = array(
    $user_id => $user_ip

        'rating_users' => serialize( $voted_users ),
        'rating_score ' => $current_score
        'file_id' => $file_id
    array( '%s', '%d' ),
    array( '%d' )

So I feel like in between the time I (retrieve the current list of users who have voted / score…verify if this is a valid vote…and then adjust/update the values back into the database) another user could have initiated the same process – and thus are dealing with “wrong” data. Data would be lost as one process would override the other’s upon the wpdb->update call.

I haven’t verified this, as emulating a race condition is difficult, but seems valid – what is a better method of performing the above that wouldn’t result in this issue?

FTLRalph 3 years 2020-03-31T20:50:50-05:00 0 Answers 70 views 0

Leave an answer