mysql之如何避免 MySQL 中的竞争条件
我正在开发的应用程序中存在潜在的竞争条件,我想在查询中考虑并避免这种情况。
总结申请流程...
在
entries
表中新建一行:INSERT INTO entrys (name, email) VALUES ( 'Foo Bar', 'foo@example.com' );
通过检查时间敏感的
prizes
表来确定 Bar 先生是否获胜:SELECT id FROM prizes WHERE various_time_conditions = 'met' AND id NOT IN (SELECT prize_id FROM entries);
如果他是赢家,则相应地更新他的输入行:
UPDATE 条目 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
添加到查询中,因为SELECT
没有 FOR UPDATE
不会等待锁。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。