MySQL由多个用户更新同一行,如计数器


MySQL updating same row by multiple users like counter

我正在尝试为用户帖子增加一个类似的计数器。一个帖子在我的MySQL表有一个字段喜欢显示多少喜欢这个特定的帖子有。现在,如果多个用户同时点赞同一篇帖子会发生什么呢?我认为这将导致冲突或不正确的增量?如何避免这种情况,我是否需要锁定行,或者我有哪些选项?

我的查询可以像这样:

UPDATE posts
    SET likes = likes + 1,
    WHERE id = some_value

同样,当用户不喜欢一个帖子时,应该减去-> likes -1

谢谢你的帮助!

这是一个足够简单的查询:

UPDATE mytable SET mycolumn = mycolumn + 1;

这样,即使你同时有很多人喜欢,查询也不会在同一时间运行,所以你最终会得到正确的数字。

这样的查询在几分之一秒内运行,所以你不需要担心多个用户点击它们,除非你有数百万用户,然后你将有很多问题与查询有关。

有人同时点赞同一篇帖子只会在长而复杂的查询中引起问题。

对于增量来说,这应该绰绰有余,否则整个SQL将变得无用。

UPDATE posts
SET likes = likes + 1
WHERE id = some_value

您总是可以以编程方式运行此查询两次,看看会发生什么。我可以保证它从0到2。

someTableAdapter.LikePost(postID);
someTableAdapter.LikePost(postID);

您所描述的称为竞态条件(例如,race to finish)。有点像和两个人玩抢椅子游戏,但只有一把椅子)。我相信如果你研究过事务,你也许能够实现你的代码并拥有伪并发之类的东西。这里有一个MySQL手册的链接。

MySQL 5.1 Manual: Transactional and Locking Statements

YouTube: MySQL Transactions

"MySQL为InnoDB表使用行级锁来支持多个会话同时写访问,使它们适合多用户,高并发和OLTP应用

MySQL对MyISAMMEMORYMERGE表使用表级锁,一次只允许一个会话更新这些表,使它们更适合只读、只读或单用户应用。"

MySQL Manual, 8.7.1: Internal Locking Methods


但是,如果事务太多,请确保您至少使用InnoDB存储引擎,如果您使用ACID兼容的数据库并具有适当的隔离级别,您应该没问题。

有很多好的参考资料,但希望我已经为你指出了正确的方向。

安东尼