gpt4 book ai didi

php - 防止 MySQL 和 InnoDB 并发访问和插入

转载 作者:行者123 更新时间:2023-11-30 01:16:13 26 4
gpt4 key购买 nike

我目前正在制作一个立即获胜的游戏,规则如下:第一个在最后一个注册后至少半小时注册的用户获胜。所以用户每半小时就可以中奖一次。如果几个小时内没有人注册,则第一个注册的人获胜。

服务器使用 PHP 5.2.0,这说明我不使用 DateTime 类。我的获胜表是 InnoDB。

我的脚本的这一部分在用户注册时由每个客户端调用,并决定用户是否获胜:

$currentTime = date("Y-m-d H:i:s");

// We're looking for the last winner in the winners table
$res = $dbh->query("SELECT date FROM winnertable ORDER BY id DESC")->fetch(PDO::FETCH_ASSOC);

if(empty($res)){
// If there is no last winner then the user wins
$winner = true;
}else{
// If there is already a last winner, we check the date of win, if superior to half an hour, the user wins
if(strtotime($currentTime)-strtotime($res["date"])>=1800){
// Last winner was half an hour ago : winner
$winner = true;
}
}

// if the winner flag is set to true, add the user id to the winners table along with the date of winning
if($winner){
$dbh->query("INSERT INTO winnertable (id_main, date) VALUES ('".$_SESSION['id']."', '".$currentTime."')");
}

下一页必须向用户显示结果,以便他知道自己是否获胜。所以我不能让 CRON 工作事后决定。

这个脚本是有缺陷的,因为如果多个客户端同时访问,它可能会让多个客户端获胜。

我读过一些解决方案:

  • 使用锁:但我不知道性能成本。另外,我读到 MyIsam 表锁定了整个表,而 InnoDB 表只锁定了标记为更新的选定行。我不知道接下来该做什么。
  • 使我的“日期”列唯一应该可以防止多次插入同一日期,这似乎是一个优雅的解决方法,但似乎有点太容易被信任,我真的很想听听您的建议。

最佳答案

您可以做的是在这种情况下添加一个进一步的阶段,从而您有另一个临时表来存储“潜在”获胜者 - 满足获胜标准的获胜者。然后对其运行 SELECT 作为辅助操作,按日期排序,索引按升序排列,限制为 1。将该值添加到真正的获胜者表中,并将其作为下一次获胜计算的基础,并清除临时表。这样你就只能得到一个获胜者。当然,这会增加开销,但它只会每半小时发生一次,所以我认为这不应该是一个太大的问题。

关于php - 防止 MySQL 和 InnoDB 并发访问和插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19034088/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com