5

我知道以前有人问过这个问题,但我仍然很困惑,如果可能的话,我想在开始编程之前避免任何问题。

我计划在任何给定时间建立一个至少有 100 个活跃用户的内部网站。用户将发布一个项目(以 0 作为其值插入到 db 中),该项目将通过 php 站点(db 查询)显示。然后,用户可以选择按下按钮并将该项目锁定为他们的(将该项目的值分配为他们的 id)

如何确保 2 个或更多用户不会同时检索同一个项目。我知道在像 c++ 这样的编程中,我只会使用普通的 ol 互斥锁。它们是 mysql 中的等价物,它只会锁定一个这样的项目条目吗?我已经看到对 LOCK_TABLES 和 GET_LOCK 以及许多其他的引用,所以我仍然对什么是最好的感到非常困惑。

许多人都有可能竞相按下一个按钮,如果多人得到确认,那将是灾难性的。

我知道这是竞争条件的一个典型例子,但 mysql 对我来说是陌生的领域。

我显然会在更新之前查询该项目的值并确保它没有写入,但是确保避免这种竞争条件的最佳方法是什么。

提前致谢。

4

3 回答 3

2

为此,您需要以某种方式锁定记录。添加一列 LockedBy 默认为 0。

当有人按下按钮时,执行类似于以下的查询:

UPDATE table SET LockedBy= WHERE LockedBy=0 and id=;

更新后验证受影响的行(在 php mysql_affected_rows 中)。如果值为 0,则表示查询没有更新任何内容,因为 LockedBy 列不为 0,因此被其他人锁定。

希望这可以帮助

于 2013-07-16T21:32:35.190 回答
2

当您发布一行时,将该列设置为 NULL,而不是 0。

然后,当用户更新该行以使其成为自己的行时,按如下方式更新它:

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

COALESCE() 返回它的第一个非空参数。因此,即使您和我同时更新,第一个提交的也可以设置值。第二个不会覆盖该值。

于 2013-07-16T21:38:01.697 回答
0

你可以考虑交易

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

如果您发现错误,您还可以回滚事务之间的所有查询!

于 2013-08-27T00:08:10.563 回答