12

我正在开发一个积分系统,该系统将根据他们的积分为我网站上的用户提供排名,每当有人检查他的个人资料页面时,我都会给用户 +1 分。假设用户有 200 分,在同一时间有 10 个用户检查他的个人资料页面,据我了解,代码将得到 200 加 1,如果 10 个用户同时在,结果将是 200 + 1 = 201 ,数据库将如何运作?

从逻辑上讲,它只会计算一次访问,因为用户检查配置文件的时间是 200,所以当 MYSQL 更新发生时,它总是 201。我正确吗?

4

1 回答 1

31

如果您选择现有的点数,在客户端中添加一个,然后将更新后的值写回数据库,那么您就有了竞态条件。正如您所指出的,某些观看次数可能不会被计算在内。

相反,您应该尝试使用原子更新并避免该问题:

UPDATE user SET points = points + 1 WHERE id = 42

另一种方法是使用SELECT ... FOR UPDATE. 从文档中:

如果将 FOR UPDATE 与使用页锁或行锁的存储引擎一起使用,则查询检查的行将被写锁定,直到当前事务结束。使用 LOCK IN SHARE MODE 设置一个共享锁,允许其他事务读取检查的行,但不能更新或删除它们。请参阅第 14.2.8.3 节,“SELECT ... FOR UPDATE 和 SELECT ... LOCK IN SHARE MODE 锁定读取”</p>

于 2012-11-06T11:33:28.510 回答