Обработка одновременных запросов MySQL от разных пользователей - PullRequest
3 голосов
/ 10 февраля 2012

У меня есть система регистрации PHP / MySQL, которая ограничивает количество людей, которые могут что-то подписать.Итак, скажем, есть 5 доступных мест, и 4 из них уже заполнены.Теперь 2 разных пользователя, которые вошли в систему, отправляют форму в одно и то же время , которая выполняет запрос MySQL для добавления этого человека в список.

Упрощенно, логика PHP выглядит примерно так:

if($numberOfSpotsTaken < 5) {
    //add user to list
}
else {
    //don't add user to list
}

Теперь, поскольку оба пользователя отправляют запрос одновременно, когда код проверяет, сколько мест занято, для обоих будет меньше 5.В итоге происходит то, что оба запроса проходят, и 6 человек попадают в список, когда предполагается, что лимит составляет 5.

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

Ответы [ 4 ]

2 голосов
/ 11 февраля 2012

Мне удалось решить эту проблему с помощью методов PDO beginTransaction(), rollBack() и commit() для предотвращения перебронирования.

Упрощенно, вот что я сделал:

<?php

$db->beginTransaction();

//add to list
$sth = $db->prepare("INSERT INTO...");
$sth->execute();

//select count from list
$sth = $db->prepare("SELECT ... FROM ...");
$sth->execute();

//check to see whether the list is overbooked -- in this case, 5 is the list limit
if($sth->rowCount() > 5) {
    $db->rollBack();
}
else {
    $db->commit();
}

?>
0 голосов
/ 10 февраля 2012

Я искал для вас ответ и нашел это:

Транзакционная блокировка БД

0 голосов
/ 10 февраля 2012

Технически ваш сценарий может произойти, но это почти невозможно. MySQL допускает множественные вставки, в которые входит получение эксклюзивной блокировки. См. Документацию MySQL здесь. http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html

0 голосов
/ 10 февраля 2012

MySQL позволяет одному пользователю одновременно выполнять запись в одну базу данных.

Я бы порекомендовал вам проверить загрузку страницы И при отправке. Если вы не проверяете все (предоставленные пользователем данные, доступность и т. Д.) На стороне сервера, то вы сделаете свои сценарии очень небезопасными.

Если вы действительно думаете, что кто-то может проскользнуть за несколько микросекунд, то после проверки «сценария» проверьте сценарий, чтобы узнать, сколько записей в нем есть. Если их слишком много, удалите последние записи до правильного номера.

Удостоверьтесь, что вы так думаете, и обрабатывайте любые ошибки: D

...