我目前正在使用SKIP LOCKED FOR UPDATE
这样安排任务:
UPDATE task
SET started_at = NOW()
WHERE id IN (
SELECT id
FROM task
WHERE /* ... bunch of logic ... */
LIMIT 1
FOR UPDATE SKIP LOCKED
)
RETURNING id
我想抽象用于使用视图选择未完成任务的子查询,例如
CREATE VIEW outstanding_task AS
SELECT *
FROM task
WHERE /* ... bunch of logic ... */
然后使用视图选择任务进行调度,例如
UPDATE task
SET started_at = NOW()
WHERE id IN (
SELECT id
FROM outstanding_task
LIMIT 1
FOR UPDATE SKIP LOCKED
)
RETURNING id
在此设置中使用视图吗SKIP LOCKED FOR UPDATE
?即它是否保证不会选择相同的 ID?
如何测试才能确定?
它确实按预期工作。
要测试它,启动两个会话并使用显式事务,例如
第 1 节:
第 2 节:
假设有一个未完成的任务
id=1
,那么第一个事务应该返回一行而第二个不应该。