0

私はPHPでこの宝くじゲームを持っています。これは非常に単純で、3つのテーブルで構成されています。

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人のユーザーが常に「TRYTOWIN」をクリックしています。管理者は、テーブルwingamesにアワードIDを挿入することがあるため、次にクリックしたユーザーがこのアイテムを獲得します。

このボタンはこれを行います:wingameslimit1からid_awardを選択します。-行がない場合-ユーザーがゲームに負けた場合、このクエリが実行されます。allgames(id_user、won_game、award_id)の値(43、false、0)に挿入します。-行が1つある場合-ユーザーがゲームに勝ち、ソフトウェアが次の2つのクエリを実行します。allgames(id_user、won_game、award_id)の値(43、true、5)に挿入します。wingamesから削除します。

1つの問題があります。「wingamesから削除」クエリが実行されるまで、別のユーザーがそのテーブルから、自分に賞があることを読み取ります。したがって、2人のユーザーが同時にボタンをクリックすると、勝者が1人ではなく2人になる可能性があります(すでにそうなっています)。そして、それは大きな問題です。なぜなら、私は1つではなく2つの賞を与えなければならないからです。

インターネットで「ロックテーブル」の回避策を探しましたが、適切な例が見つかりませんでした。

(おそらく迅速で汚い)解決策はありますか?

4

1 に答える 1

0

zerkmsが述べたように、更新のためにSELECT..が必要です。トランザクションが終了するまでゲームをロックします。

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ステートメントがどのように機能するかを確認するには、2つのインタラクティブクライアントでこれを試す必要があります。

于 2012-10-06T13:18:28.297 に答える