update用法 - sql transaction mysql



如何避免在MySQL中的競爭條件 (1)

在我正在開發的一個應用程序中,我有一個潛在的競爭條件,我想在這個應用程序中解釋和避免。

總結應用程序流程...

  1. entries表中創建一個新行:

    INSERT INTO entries ( name, email ) VALUES ( 'Foo Bar', '[email protected]' );

  2. 通過檢查一個時間敏感的prizes表來看看Bar先生是否是贏家?

    SELECT id FROM prizes WHERE various_time_conditions = 'met' AND id NOT IN ( SELECT prize_id FROM entries );

  3. 如果他是贏家,相應地更新他的輸入行:

    UPDATE entries SET prize_id = [prize id] WHERE id = [entry id];

由於每個獎項只能發放一次,所以我需要消除其他進程可以查詢獎勵表並更新上述步驟2和步驟3之間的入口表的任何競爭條件的可能性。

我一直在做一些研究,發現一些有關事務的信息(我所有的表都使用InnoDB),並且使用MySQL的SELECT ... FOR UPDATE語法,但是我很困惑哪個是最適合我的解決方案。


你將要鎖定獎金記錄。 所以,如果你不打算使用類似於winner_id的東西,那麼在獎品表上添加一些可用性標誌(可能是一個默認值)。 像這樣的東西:

SELECT id FROM prizes WHERE ... AND available = 1 FOR UPDATE

然後設置可用性,如果你確實分配獎品:

UPDATE prizes SET available = 0 WHERE id = ...

當然,你需要將其包裝在一個事務中。

確保每次檢查獎品是否可用時,都會向查詢添加AND available = 1 FOR UPDATE ,因為沒有FOR UPDATESELECT不會等待鎖定。





race-condition