处理来自不同用户的同时MySQL查询

时间:2012-02-10 03:19:31

标签: php mysql transactions

我有一个PHP / MySQL注册系统,可以限制可以注册某些内容的人数。所以,假设有5个可用点,其中4个已经满了。现在,2个登录的用户提交了一个表单完全同时执行MySQL查询以将该人添加到列表中。

简化,PHP逻辑看起来像:

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

现在,因为用户同时提交请求,当代码检查以查看拍摄的点数时,两者都将低于5。最终发生的事情是,当限制应该是5时,两个请求都会通过,6个人最终会出现在列表中。

如何防止出现这种情况,以便同时提交请求的两个(或更多)用户无法绕过有多少人注册的限制?

4 个答案:

答案 0 :(得分:2)

我能够通过使用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();
}

?>

答案 1 :(得分:0)

MySQL只允许单个用户一次写入一个数据库。

我建议您检查页面加载和提交。如果您没有检查服务器端的所有内容(用户提交的数据,可用性等),那么您将使脚本非常不安全。

如果你真的认为某人可能会在几微秒内溜进去,那么在“成功”之后检查脚本以查看有多少条目。如果太多,请将最新条目删除到正确的数字。

请确保您考虑到这一点并处理任何错误:D

答案 2 :(得分:0)

我去寻找你的答案,发现了这个:

Transactional DB Locking

答案 3 :(得分:0)

从技术上讲,你的情景可能会发生,但这几乎是不可能的。 MySQL允许多次插入,这是获取独占锁的地方。请参阅MySQL的文档。 http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html