0

我正在尝试为作业队列进行某种更新选择。我需要它来支持影响同一个表或数据库的并发进程该服务器将仅用于队列,因此每个队列的数据库是可以接受的。最初我在考虑类似以下的事情:

UPDATE state=1,ts=NOW() FROM queue WHERE ID IN (SELECT ID FROM queue WHERE state=0 LIMIT X) RETURN *

我读到这将导致竞争条件,我读到 SELECT 子查询有一个选项可以使用 FOR UPDATE,但是这将锁定行并且并发调用将被阻止,我不介意他们跳过到下一个未锁定的行。

所以我要求的是在 postgres 中拥有一个需要最少锁定整个数据库的 fifo 系统的最佳方式。

4

1 回答 1

0

执行此操作的典型方法是将其包装在 PLPGSQL 函数中,选择 FOR UPDATE NOWAIT,然后使用异常处理跳过锁定的行。

这确实会给函数带来一些额外的开销,因为即使没有异常,异常处理也需要额外的处理器周期来管理。

作为一个非常简单的例子:

 CREATE OR REPLACE FUNCTION get_all_unlocked_customers() RETURNS SETOF customer
 LANGUAGE PLPGSQL AS
 $$
 RETURN QUERY SELECT * FROM customer FOR UPDATE NOWAIT;
 EXCEPTION
    WHEN LOCK_NOT_AVAILABLE THEN
    -- NO NEED TO DO ANYTHING
    END;
 END;
 $$;
于 2013-12-01T03:38:45.413 回答