我有一些表代理。那里存储了代理。应用程序是多线程的。每个线程都从代理表获取代理。我需要使用代理,即每次代理使用的频率必须偶然相等。有些字段“ last_usage”的时间戳为微秒。

现在,要实现此目标,我要执行下一个操作:阻止表,使用较旧的last_usage选择一个代理,然后更新所选代理的last_usage并解锁表。

表引擎是inno_db。

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

SET @uids := null;
UPDATE footable
   SET foo = 'bar'
 WHERE fooid > 5
   AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;


我认为它应该具有相同的效果。因为mysql在执行更新时应该阻塞行或表。并且另一个线程应该不能选择该行。

我可以使用第二个解决方案来实现我的目标吗?哪种方法更好?或者您可以建议更好的方法?

最佳答案

干净的方法是在单个事务中使用两个查询:

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;


FOR UPDATE用于锁定选定的行,直到提交事务。

09-26 08:21