等到行可用 SKIP LOCKED

Wait until row becomes available with SKIP LOCKED

我正在使用 PostgreSQL 和 SKIP LOCKED 来实现 What is SKIP LOCKED for in PostgreSQL 9.5? 中描述的队列。基本上,这工作正常,但有时当工作人员很快并且没有那么多工作要做时,队列 运行 是空的。 IOW:SELECT 没有找到任何东西,因此语句 运行s 最后什么也没做,我们就完成了。

现在我想做的是在新行一进来就重新运行语句,然后再试一次(尽管所有其他工作人员也可能会尝试这样做)。这最终归结为轮询数据库,这不是最优的。

当然,我可以使用 PostgreSQL 的 NOTIFY 功能在写入新行后通知工作人员,但我想知道这在 SELECT 本身是否可行,例如离开它打开直到它成功并且 return 是一条记录?诸如 long-运行ning SELECT 之类的东西,只要它需要 return 结果就会保持打开状态。

这可能吗?

根据这些答案,强制 select 查询等待结果是不可能的:

一个想法可能是在 table 变为空时锁定它,并在插入之前释放它,但这听起来令人毛骨悚然......(请参阅:)

我的意见是使用NOTIFY,即使不能完全达到你的预期,这里table也会更合适,因为它就是为这种情况而制作的。

当然,您可以使用简单的 WHILE 循环实现一些 get_item() PL/SQL 方法,但我认为这不是您要找的...

只是为了进一步了解,等待队列 return 一个项目的 PLSQL 函数:

CREATE OR REPLACE FUNCTION get_item() 
RETURNS int8 
LANGUAGE plpgsql
AS
$$
DECLARE
    count int8 = 0;
    id int8;
BEGIN
    WHILE id IS Null LOOP
        DELETE FROM queue
        WHERE itemid = (
          SELECT itemid
          FROM queue
          ORDER BY itemid
          FOR UPDATE SKIP LOCKED
          LIMIT 1
        )
        RETURNING itemid INTO id;
        IF id IS Null THEN
           PERFORM pg_sleep(1);
        END IF;
    END LOOP;

    RETURN id;
END;
$$;