【问题标题】:Postgres SELECT COUNT ... FOR UPDATEPostgres SELECT COUNT ... 更新
【发布时间】:2016-10-26 10:47:36
【问题描述】:

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

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 子查询中添加 FOR UPDATE 来获得第二个原子查询。但我无法将 FOR UPDATE 添加到第一个查询中,因为聚合函数不允许使用 FOR UPDATE

我怎样才能使这部分成为原子事务?

【问题讨论】:

  • select for update .. skip locked: blog.2ndquadrant.com/…
  • @a_horse_with_no_name 这看起来很有希望!
  • @a_horse_with_no_name 这根本无助于解决我的问题,它只是让 FOR UPDATE 更加优化,但无论如何感谢

标签: sql postgresql select-for-update


【解决方案1】:

您可以在子查询中执行 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
        )
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    相关资源
    最近更新 更多