这是我正在尝试做的伪代码:
rate_count = SELECT COUNT(id) FROM job WHERE last_processed_at >= ?
current_limit = rate_limit - rate_count
if current_limit > 0
UPDATE job SET state='processing'
WHERE id IN(
SELECT id FROM job
WHERE state='pending'
LIMIT :current_limit
)
除了并发问题,我才能使用它。当同时从多个会话运行时,两个会话都会SELECT并因此更新相同的内容:(
我可以通过在其SELECT子查询中添加FOR UPDATE来获得第二个查询原子。但是我无法在第一个查询中添加FOR UPDATE,因为聚合函数不允许使用FOR UPDATE
如何将此作品作为原子交易?
答案 0 :(得分:2)
您可以在子查询中执行FOR UPDATE:
rate_count := COUNT(id)
FROM (
SELECT id FROM job
WHERE last_processed_at >= ? FOR UPDATE
) a;
您也可以在一个查询中完成这一切:
UPDATE job SET state='processing'
WHERE id IN (
SELECT id FROM job
WHERE state='pending'
LIMIT (SELECT GREATEST(0, rate_limit - COUNT(id))
FROM (SELECT id FROM job
WHERE last_processed_at >= ? FOR UPDATE) a
)
)