如何适当地避免Mysql的竞态条件(How to properly avoid Mysql Race

2019-07-05 15:11发布

我知道这已经被问过,但我仍然感到困惑,并希望避免出现任何问题之前,我进入编程如果可能的话。

我打算在任何给定的时间具有至少100个活跃用户内部网站。 用户会后的项目(插入用0作为其值分贝)和该项目将通过一个PHP站点(分贝查询)显示。 然后,用户拿到选项按下一个按钮,并锁定该项目作为他们(分配该项目的值作为其ID)

如何确保2个或更多用户不会在同一时间获得相同的项目。 我知道像C ++我只想用纯醇互斥锁编程。 是他们在MySQL等效那里将仅锁定一个项目进入这样呢? 所以我还是对什么是最好很困惑,我看到LOCK_TABLES和GET_LOCK和许多其他的引用。

有潜力,很多人都竞相按下一个按钮,如果多人得到一个确认这将是灾难性的。

我知道这是一个竞争条件最好的例子,但MySQL的是外国领土上我。

我明明会查询该项目的价值之前,我更新它并确保它不写,但什么是确保这种竞争情况,避免的最好办法。

提前致谢。

Answer 1:

要做到这一点,你将需要以某种方式锁定该记录。 添加默认为0列LockedBy。

当有人按下按钮时执行一个查询类似这样的:

UPDATE SET表= LockedBy WHERE LockedBy = 0和id =;

更新后确认受影响的行(在PHP mysql_affected_rows)。 如果该值为0则表示,因为LockedBy列不为0,因此通过别人锁定查询没有任何更新。

希望这可以帮助



Answer 2:

在您发表行中,将列设置为NULL,而不是0。

然后,当用户更新该行,使其自身,如下更新:

UPDATE MyTable SET ownership = COALESCE(ownership, $my_user_id) WHERE id = ...

COALESCE()返回第一个非空参数。 所以,即使你和我是同时更新,提交第一个到达设定值。 第二个将不覆盖该值。



Answer 3:

您可以考虑交易

BEGING TRANSACTION;
SELECT ownership FROM ....; 
UPDATE table .....; // set the ownership if the table not owned yet
COMMIT;

,你也可以回滚事务之间的所有疑问,如果你抓住了一个错误!



文章来源: How to properly avoid Mysql Race Conditions