- 通过竞争线程阻止mysql选择同一行

表引擎是inno_db 。

另一个我的想法是使用以下解决方案:


SET @uids := null;


UPDATE footable


 SET foo = 'bar'


 WHERE fooid > 5


 AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );


SELECT @uids;



我认为它应该有同样的效果,因为mysql在执行update时应该阻止行或表,另一个线程不应选择此行。

我可以用第二个解决方案来实现我的目标?

时间:

简洁的方式是在单个事务中使用两个查询:


start transaction;



select foo_id into @foo_id


from foo_table


order by last_usage asc


limit 1


for update;



update foo_table


set last_usage = now()


where foo_id = @foo_id;



commit;



这里解释了一个innodb锁https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html

在你的情况下


SELECT * FROM footable WHERE fooid > 5


 AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) ) FOR UPDATE;



然后更新并删除具有相同会话的锁:


UPDATE footable


 SET foo = 'bar'


 WHERE fooid > 5


 AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );



...