MySQL重读/写结果

时间:2012-10-06 11:05:58

标签: mysql locking

我在PHP中有这个彩票游戏。它非常简单,它由三个表组成:

awards:
 - ID
 - award_name

wingames:
 - ID
 - ID_award

allgames:
 - ID_user
 - won_game (bool)
 - award_id (if game not won, then it is 0)

宣布,例如,比赛开始时间下午18:00。大约100名用户经常点击“尝试赢”。管理员有时会在表格中插入一个奖励ID,以便下次点击用户赢得此项目。

此按钮执行以下操作: 从wingames限制1中选择id_award; - 如果没有行 - 用户输掉游戏,则进行以下查询: 插入allgames(id_user,won_game,award_id)值(43,false,0); - 如果有一行 - 用户赢得游戏,软件会进行以下两个查询: 插入allgames(id_user,won_game,award_id)值(43,true,5); 从wingames删除;

有一个问题:在“从wingames删除”查询执行之前,另一个用户从该表中读取,他有一个奖励。因此,当2个用户同时点击按钮时,可能会发生(并且已经发生),有两个赢家而不是一个。这是一个很大的问题,因为我必须给两个奖品而不是一个。

我在互联网上查了一些“锁定表”的解决方法,但没有找到合适的例子。

你有任何(可能快速和肮脏)的解决方案吗?

1 个答案:

答案 0 :(得分:0)

正如zerkms所提到的,你需要SELECT .. FOR UPDATE。它将锁定游戏直到您的交易结束。

START TRANSACTION;

SELECT * FROM wingames FOR UPDATE;
/* from now on, only one request can continue, the others are blocked */

INSERT INTO allgames ...

DELETE FROM wingames WHERE ID = ...

COMMIT;

您应该在两个交互式客户端上尝试此操作,以查看FOR UPDATE语句的工作原理。