我有一个PHP / MySQL注册系统,可以限制可以注册某些内容的人数。所以,假设有5个可用点,其中4个已经满了。现在,2个登录的用户提交了一个表单完全同时执行MySQL查询以将该人添加到列表中。
简化,PHP逻辑看起来像:
if($numberOfSpotsTaken < 5) {
//add user to list
}
else {
//don't add user to list
}
现在,因为用户同时提交请求,当代码检查以查看拍摄的点数时,两者都将低于5。最终发生的事情是,当限制应该是5时,两个请求都会通过,6个人最终会出现在列表中。
如何防止出现这种情况,以便同时提交请求的两个(或更多)用户无法绕过有多少人注册的限制?
答案 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)
我去寻找你的答案,发现了这个:
答案 3 :(得分:0)
从技术上讲,你的情景可能会发生,但这几乎是不可能的。 MySQL允许多次插入,这是获取独占锁的地方。请参阅MySQL的文档。 http://dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html