New*_*ewb 33 mysql atomic increment thread-safety
我正在建立一个网站,我想在标准的MyISAM表中增加一个计数器.
简化示例:
UPDATE votes SET num = num + 1;
Run Code Online (Sandbox Code Playgroud)
如果多个连接正在执行相同的查询,这会导致问题,还是MySQL会处理它并锁定表或某些东西以确保没有冲突?
Tra*_*ago 23
写入是原子的,但增量也需要读取.所以问题是:你确定读取是安全的吗?换句话说,你确定另一个做增量的线程最终不会以相同的值递增吗?我有疑问.这样做的100%正确方法是.
-- begin transaction here
select counter from myCounters where counter_id = 1 FOR UPDATE;
-- now the row is locked and nobody can read or modify its values
update myCounters set counter = ? where id = 1;
-- set ? to counter + 1 programmatically
commit; -- and unlock...
Run Code Online (Sandbox Code Playgroud)
Lac*_*lev 15
MyISAM表使用表级锁定.这意味着在执行更新查询期间将锁定整个表.因此,简化用例的答案是:是的,这是线程安全的.但是,如果您使用其他存储引擎或者您的更新包含多个表,则可能不是这种情况.
以下是MySQL手册中的引用,以便更清晰:
表锁定允许多个会话同时从表中读取,但如果会话想要写入表,则必须首先获得独占访问权.在更新期间,要访问此特定表的所有其他会话必须等到更新完成.
如果适合您的设计,您还可以考虑使用自动增量列,事务或外部同步.
干杯!