我有一个简单的设置,可以在游戏中分配对手。
基本上,如果matchID为零(值来自其他位置),则需要创建一个新的匹配项,并且它将在最后一个matchID记录上执行mysql select,以确定是否有人在等待匹配项。
要查看玩家是否在等待,我们可以查看teamB空间是否为零(未占用)。但是,如果teamB有一个值,则没有人在等待,并且必须与该球员作为“ A队”进行新的比赛。
代码如下:
if ($matchID == 0)
{
$teamBquery = $conn ->query("SELECT matchID,teamBID,teamAID FROM challengeMatches ORDER BY matchID DESC LIMIT 1 ");
$teamBarray = $teamBquery->fetch(PDO::FETCH_ASSOC);
$teamBID=$teamBarray[teamBID];
$matchID=$teamBarray[matchID];
$teamAID=$teamBarray[teamAID];
if ($teamBID == 0){
$newChallenge = $conn ->query ("UPDATE challengeMatches SET managerBID='$managerID', teamBID='$teamID',matchStatus=1 WHERE matchID='$matchID'");
}else{
$filler = 0;
$matchID = $matchID+1;
$newChallenge = $conn ->query ("INSERT INTO challengeMatches (matchID,managerAID,managerBID,matchStatus,teamAID,teamBID) VALUES ('','$managerID','$filler','$filler','$teamID','$filler')");
}
}
我担心的是,由于我的经验不足,据我所知,选择信息和更新信息之间会有延迟,因此从技术上讲,两个mysql select可能会返回要使用的相同matchID。然后,甚至将matchID + 1用作变量也是有风险的,因为它可能与数据库中创建的自动增量matchID不同步。
是我的恐惧根源还是代码如此之快,以至于不值得担心的可能性?
如果我应该担心该怎么办?
最佳答案
首先,您需要确定是否确实需要解决方案来克服此问题,否则时间间隔应该很小,除非您运行一个大型站点,否则选择两个matchId的可能性很小。
但是,实际上可以在三个方面进行改进:
锁定-查看SELECT .. FOR UPDATE
或SELECT ... LOCK IN SHARE MODE
交易次数
重构数据库以首先实际更新一个限制,然后选择更新的范围