Я использую PHP + JS для создания игры. Каждая игра — человек против человека, поэтому только 2 пользователя. Это работает, но у меня проблемы с «двойным бронированием». Как это:
Шаги 3 и 4 выполняются всего за миллисекунды. Когда пользователь присоединяется к игре, я сначала проверяю, занято ли «место». Если нет — я анализирую все важные данные и т. Д., А затем устанавливаю место как занятое. Кажется, что во время разбора пользователи могут присоединиться к одной и той же игре. Это вопрос миллисекунд, как я уже говорил ранее. Но как мне предотвратить это?
Вы можете использовать неявную блокировку записи базы данных, выполнив пробуй и набор операция по занятию свободного места, примерно так:
UPDATE blackjack_hands
SET user_id = :user_id
WHERE user_id IS NULL
AND blackjack_id = :blackjack_id
AND creator = '0';
Затем проверьте количество обновленных записей (например, с помощью msqli_affected_rows) после этого решить, было ли место успешно занято (что означает, что оно было свободным).
Таким образом, второй пользователь не сможет выполнить такое же успешное обновление.
Это было бы примером пессимистической блокировки.
Приведенный выше запрос предполагает, что при создании игры вы сразу вставляете две записи: одну для user_id создателя (как вы, конечно, уже делаете) и одну для user_id неизвестного противника, инициализированного как NULL.
NB: рассмотрите возможность отойти от устаревшего mysql_*
функции. Вы могли бы использовать mysqli_*
или же PDO
интерфейс вместо.
Других решений пока нет …