我有一个包含以下列的表:[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";
}

代码只允许两个玩家注册,但有时当网站上的用户太多时,此条件将不起作用,三个用户将添加到表中。
我该怎么解决?

最佳答案

你有几个选择:
如果使用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';
}

更改表结构,使有两列player1player2(最初为NULL)并执行UPDATE live_games SET player2 = ? WHERE game_id = ? AND player2 IS NULL,然后检查受影响的行数;或
更改表结构,以便有一个额外的playerNumber列,然后在UNQUE上创建一个复合(game_id, playerNumber)索引。

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

10-11 02:54