防止在MySQL中同时进行数据库更新而不锁定表

时间:2014-12-03 11:38:18

标签: mysql

我有一个多人纸牌游戏。每场比赛由4名球员进行。每位玩家都会获得一个席位(1,2,3,4),玩家点击加入游戏,当所有4个席位都填满后,游戏就可以开始了。

数据库中的游戏条目如下:

id | status
13 | 3

status是填充座位的数量。每次新玩家加入时它都会递增。现在我有一个问题。有时2名玩家同时发送请求,并且他们都被添加到同一个座位。在上面的示例中,收到了两个请求,突然有5个玩家在游戏中,其中2个被分配到4个座位。

显然在我更新之前,我检查一下还没有4名玩家。

类似的东西:

if($row['status'] < 4){
    mysql_query("update games set status=status+1 where id=13");
}

从逻辑上讲,这应该可以防止status超过4,但如果有很多玩家加入游戏,那么status通常会因为多个玩家同时加入而变为5。

我想我可以通过使用表锁来防止这种情况,但我不想锁定整个表以便只更新一行(同时可能有50个游戏正在进行中)。

要解决这个问题必须有一个可靠的方法,对吗?

2 个答案:

答案 0 :(得分:2)

您可以将约束合并到更新语句本身中,以便在DB中进行规范:

update games set status = coalesce(status, 0) + 1 
where id=13
and coalesce(status, 0) < 4

答案 1 :(得分:1)

您还可以使用&#34;选择更新。&#34;

类似的东西:

sql:
begin(); // Need to be in a transaction.
select status from $YOUR_TABLE where $SOMETHING for update
code:
if(status<4)
   Set new status in database.
commit();

选择更新锁定行(不是数据库,只有匹配where的单行)。