I am using PHP + JS to create a game. Every game is person vs person, so only 2 users. It works, but I have trouble with "double bookings". Like this:
The steps 3 and 4 happen with only milliseconds between. When a user joins a game, I first check if the "seat" is taken. If not - i parse all essential data, etc, and then i set the seat as taken. During the parsing, it seems as users can join the same game. This is a matter of milliseconds, as I stated earlier. But how do i prevent this?
You could make use of an implicit database record lock, by performing a kind of test-and-set operation for taking a free seat, something like this:
UPDATE blackjack_hands
SET user_id = :user_id
WHERE user_id IS NULL
AND blackjack_id = :blackjack_id
AND creator = '0';
Then check the number of updated records (for instance with msqli_affected_rows) after that to decide if the seat was successfully taken (which implies it was free).
That way it will not be possible for a second user to make the same successful update.
This would be an example of pessimistic locking.
The above query assumes that during game creation, you would insert two records immediately, one for the creator's user_id (as you certainly do already), and one for the unknown opponent's user_id, initialised as NULL.
NB: Consider moving away from the deprecated mysql_*
functions. You could use the mysqli_*
or PDO
interface instead.