试图了解延迟的作业轮询查询

时间:2017-07-18 03:56:59

标签: sql ruby-on-rails haskell delayed-job

我正在尝试将Delayed Job移植到Haskell,并且我无法理解DJ在查询下一个作业时查询的WHERE子句:

UPDATE "delayed_jobs"
SET locked_at = '2017-07-18 03:33:51.729884',
    locked_by = 'delayed_job.0 host:myhostname pid:21995'
WHERE id IN (
  SELECT id FROM "delayed_jobs"
  WHERE
  (
      (
        run_at <= '2017-07-18 03:33:51.729457'
        AND (locked_at IS NULL OR locked_at < '2017-07-17 23:33:51.729488')
        OR locked_by = 'delayed_job.0 host:myhostname pid:21995'
      )
      AND failed_at IS NULL
  ) ORDER BY priority ASC, run_at ASC LIMIT 1 FOR UPDATE) RETURNING *

WHERE子句的结构如下:

(run_at_condition AND locked_at_condition OR locked_by_condition) 
AND failed_at_condition
  • run_at_condition AND locked_at_condition OR locked_by_condition中是否缺少一组内括号? AND / OR子句的优先级是什么?
  • 似乎locked_by_condition有什么目的可以获取当前DJ流程已锁定的作业?

1 个答案:

答案 0 :(得分:1)

声明可能没问题。整个声明的上下文是通过设置locked_at / locked_by字段来锁定优先级最高的作业

where条件是这样的:“如果run_at比现在更早(它应该到期)并且,它要么没有锁定,要么在四个多小时前锁定了...... 或者

关于第二个问题,AND的优先级高于OR

SELECT 'yes' WHERE false AND false OR true;   -- 'yes', 1 row
SELECT 'yes' WHERE (false AND false) OR true; -- 'yes', 1 row
SELECT 'yes' WHERE false AND (false OR true); -- 0 rows

前两个语句表示相同的东西,第三个是不同的。

第二点可能只是一种粗略的所有制?如果当前进程是锁定某个进程的进程,则它应该能够覆盖该锁。