我正在尝试将延迟作业移植到 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 流程锁定的工作?!
这个陈述可能没问题。整个语句的上下文是通过设置其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
前两个陈述的意思相同,第三个陈述不同。
第二点可能只是一种粗略的所有制?如果当前进程是锁定某些内容的进程,则它应该能够覆盖该锁定。