sql – Postgres SELECT COUNT … FOR UPDATE

这是我正在尝试做的伪代码:

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

我怎样才能将这件作品作为原子交易?

最佳答案 您可以在子查询中执行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
        )
)
点赞