0

我在 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 个用户不断点击“TRY TO WIN”。管理员有时会在桌面 wingames 中插入奖励 ID,以便下一个点击用户赢得此项目。

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

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

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

您有任何(可能是快速而肮脏的)解决方案吗?

4

1 回答 1

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 语句是如何工作的。

于 2012-10-06T13:18:28.297 回答