gpt4 book ai didi

php - mysql 中一次只允许 1 个打开条目

转载 作者:行者123 更新时间:2023-11-29 11:37:05 25 4
gpt4 key购买 nike

我开发了一个游戏,通过ajax使用php和jquery。

本质上,当向服务器发出请求时,如果还没有打开游戏,服务器将创建一个新游戏。我的游戏数据库表如下所示:

id | closed | time

游戏结束后,Where close 将被设置为 1,time 是游戏创建时的 unix 时间戳。

现在重要的是,在任何给定时间,表中只能有 1 场比赛结束 = 0。

为此,我使用以下 php 代码

$query = "SELECT id FROM games WHERE closed = '0' LIMIT 1";
$result = $this->database->query($query);
if ($result->num_rows == 0) {
$query = "INSERT INTO games_roulette SET time = '".time()."'";
$result = $this->database->query($query);
return $this->database->insert_id;
} else {
return false;
}

有时候会创建 2 个游戏,我相信这是因为在同一时间发送了 2 个请求,因为当有 2 个游戏打开时,时间值总是完全相同。

有什么方法可以让我 100% 确定表中永远不会有 2 场比赛结束 = 0 的比赛吗?

最佳答案

正如您所怀疑的,您最终得到 2 条记录的可能原因是并发性。如果两个进程首先分别运行 SELECT 查询,它们都会获得继续的绿灯,并且都将运行 INSERT。所以你最终会得到 2 个(或更多!)这样的行。

传统上,您会使用事务或锁来避免这种情况,但还有一个 SQL“技巧”允许单个原子查询来完成此操作:

INSERT INTO  game_rouletteSELECT NULL, x.closed, NOW()  FROM    (SELECT '0' as closed) x    LEFT JOIN game_roulette g ON x.closed = g.closed  WHERE    g.id IS NULL

只是为了解释一下它是如何工作的:它是一个 INSERT ... SELECT 语法,其中 SELECT 查询仅在没有 game_roulette 所在行的情况下才会产生结果.close'0'。反过来,这是通过创建单行表x,然后在关闭上针对game_roulette执行LEFT JOIN来完成的code> 列并使用 g.id IS NULL 约束。

完成此查询后,如果需要,应用程序可以检查 INSERT 的结果,就像处理任何其他查询一样,以了解是否插入了任何行结果。

注意:如果您在大型表上执行此操作,则应该测量查询性能和/或确保闭合列上有索引并且正在使用该索引。

关于php - mysql 中一次只允许 1 个打开条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36394129/

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