php 如何在mysql中为当前值添加一个数字(同时多次)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13250066/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add a number to a current value in mysql (multiple times at the same time)?
提问by Mohamed Said
I'm working on a points system that will give users on my site a ranking based on their points, I'm giving the user +1 points whenever someone checks his profile page. Let's say the user has 200 points, on the same exact time 10 users checked his profile page, from my understanding the code will get 200 adds 1 and the result will be 200 + 1 = 201 if the 10 users are in at the same time, how will the database act?
我正在开发一个积分系统,该系统将根据他们的积分为我网站上的用户提供排名,每当有人查看他的个人资料页面时,我都会给用户 +1 分。假设用户有 200 点,在同一时间 10 个用户检查了他的个人资料页面,根据我的理解,如果 10 个用户同时在,代码将得到 200 加 1,结果将是 200 + 1 = 201 ,数据库将如何运作?
Logically it will count only one visit because the time users checked the profile the value was 200, so when the MYSQL update happens it will be always 201. Am I correct ?
从逻辑上讲,它只会计算一次访问,因为用户检查配置文件的时间值为 200,所以当 MYSQL 更新发生时,它将始终为 201。我正确吗?
回答by Mark Byers
If you select the existing number of points, add one in the client, and then afterwards write the updated value back to the database then you have a race condition. As you point out, it's possible that some views won't be counted.
如果您选择现有的点数,在客户端添加一个,然后将更新的值写回数据库,那么您就有了竞争条件。正如您所指出的,有些观看次数可能不会被计算在内。
Instead you should try to use an atomic update and avoid the problem:
相反,您应该尝试使用原子更新并避免该问题:
UPDATE user SET points = points + 1 WHERE id = 42
An alternative is to read with SELECT ... FOR UPDATE. From the documentation:
另一种方法是使用SELECT ... FOR UPDATE. 从文档:
If you use FOR UPDATE with a storage engine that uses page or row locks, rows examined by the query are write-locked until the end of the current transaction. Using LOCK IN SHARE MODE sets a shared lock that permits other transactions to read the examined rows but not to update or delete them. See Section 14.2.8.3, “SELECT ... FOR UPDATE and SELECT ... LOCK IN SHARE MODE Locking Reads”
如果将 FOR UPDATE 与使用页锁或行锁的存储引擎一起使用,则查询检查的行将被写锁定,直到当前事务结束。使用 LOCK IN SHARE MODE 设置一个共享锁,允许其他事务读取检查的行但不能更新或删除它们。见第 14.2.8.3 节,“SELECT ... FOR UPDATE 和 SELECT ... LOCK IN SHARE MODE 锁定读取”

