等待,直到行变得可用,并且“跳过锁定”

时间:2019-07-05 20:24:48

标签: sql postgresql wait

我正在将PostgreSQL与SKIP LOCKED配合使用来实现队列,如What is SKIP LOCKED for in PostgreSQL 9.5?中所述。基本上,这可以很好地工作,但是有时当工作人员工作很快且没有太多工作要做时,队列将排空。 IOW:SELECT找不到任何东西,因此该语句运行,最后什么也没做,我们就完成了。

现在,我想做的就是在新行进入后立即重新运行该语句,然后重试(尽管所有其他工作人员也可能尝试这样做)。最终,这取决于轮询数据库,也就是说,这不是最佳选择。

当然,一旦写入新行,我当然可以使用PostgreSQL的NOTIFY功能通知工作人员,但是我想知道SELECT本身是否可行,例如将其打开直到成功并返回记录?诸如长期运行的SELECT之类的东西只要打开返回结果就保持打开状态。

这可能吗?

1 个答案:

答案 0 :(得分:2)

根据这些答案,这不可能迫使选择查询等待结果:

一个想法可能是在表变成空时锁定表,并在插入之前释放表,但这听起来令人毛骨悚然...(请参阅:https://stackoverflow.com/a/17525747/4279120

我的观点是,使用NOTIFY(即使无法完全达到您的期望)在这里更合适,因为它是为此类情况而设计的。

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

为了进一步了解,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;
$$;