php - Mysql插入冲突

标签 php mysql

我有一个包含以下列的表:[user_id][game_id] 当两个玩家加入游戏时我需要关闭游戏。 我使用了这段代码:

if(mysql_num_rows(mysql_query("SELECT user_id FROM live_games WHERE game_id = '$gid'"))<2){
mysql_query("INSERT INTO live_games (user_id, game_id) VALUES ('$uid', '$gid')");
echo "You have joined the game";
}else{
echo "Table is full";
}

该代码仅允许两个玩家注册,但有时当网站中有太多用户时,此条件将不起作用,并且将在表中添加三个用户。 我该如何修复?

最佳答案

您有几个选择:

  1. 如果使用 InnoDB 存储引擎,请使用 SELECT ... FOR UPDATE 执行锁定读取。在与INSERT相同的交易中声明。

    使用 PDO:

    $dbh = new PDO("mysql:dbname=$dbname;charset=utf8", $username, $password);
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    
    $dbh->beginTransaction();
    $qry = $dbh->prepare('
      SELECT COUNT(*) FOR UPDATE FROM live_games WHERE game_id = ?
    ');
    $qry->execute([$gid]);
    
    if ($qry->fetchColumn() < 2) {
      $qry = $dbh->prepare('
        INSERT INTO live_games (user_id, game_id) VALUES (?, ?)
      ');
      $qry->execute([$uid, $gid]);
      if ($qry->rowCount() && $dbh->commit()) echo 'You have joined the game';
    } else {
      $dbh->rollBack();
      echo 'Table is full';
    }
    
  2. 更改表结构,使之有两列,player1player2 (最初 NULL )并执行 UPDATE live_games SET player2 = ? WHERE game_id = ? AND player2 IS NULL ,然后检查受影响的行数;或

  3. 更改表结构,以便有一个额外的 playerNumber列,然后创建一个复合 UNQUE索引超过(game_id, playerNumber) .

关于php - Mysql插入冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12447999/

相关文章:

php - 未转义的美元符号不会引发错误; PHP 处理边缘情况?

php - 如何在 foreach 查询中插入第二个 foreach 查询?

php - 从 mysql 获取数组创建命名 session 数组

php - 使用复选框过滤 MySQLi

php - 使用AND和OR的Elasticsearch NOT bool 运算

php - PHP MYSQL覆盖最后一个连接链接

php - 链接 css Assets 的 Laravel 5 问题

mysql - 如何在其他查询MySQL中使用select子查询

mysql - 通过 SSH 在 AWS RDS MySQL 数据库实例上执行查询

mysql - 什么是 mysql 中每天的查询缓存修剪数