0

我正在使用 postgres 构建一个 FIFO 队列,并基于 apinstein 对作业队列的回答作为具有多个消费者的 SQL 表(PostgreSQL)

问题是,如果我使用事务,那么语句看起来像:

    begin;
lock table queued_message in exclusive mode;
update 
    queued_message
set 
    status='IN_PROGRESS'
where
    id in (
        select
            id
        from
            queued_message
        where
            status='SUBMITTED' and queue='BACKFILL_REQUEST'
        order by 
            id asc
        limit 1
    )
returning *;
commit;

然后我的返回值被丢弃。如果我在没有开始/提交的情况下运行相同的语句,则记录集返回正常。

显然我更喜欢交易;没有它,该语句甚至可能不安全。那么如何返回我提交的记录集呢?

编辑 我正在标记答案,因为它让我走上了正确的轨道,但这是我最终得到的功能:

CREATE TYPE returned_message as (id bigint, body json, status character varying(50) , queue character varying(150), last_modified timestamp without time zone)

CREATE OR REPLACE FUNCTION get_next_message(desiredQueue character varying(150)) 
RETURNS returned_message AS $$
    DECLARE result returned_message;
    BEGIN
    lock table queued_message in exclusive mode;
    update queued_message
    set 
        status='IN_PROGRESS'
    where
        id in (
        select
            id
        from
            queued_message
        where
            status='SUBMITTED' and queue=desiredQueue
        order by 
            id asc
        limit 1
        )
    returning * into result;
    RETURN result; 
END;$$LANGUAGE plpgsql; 


select * from get_next_message('BACKFILL_REQUEST')
4

1 回答 1

0

您可以创建一个返回所需值的函数。每个函数都作为事务执行。不要放置“开始;” 和“承诺”;在函数体内。我相信下面的功能应该可以工作。

create or replace function set_in_progress()
returns setof queued_message 
language sql as $$
    lock table queued_message in exclusive mode;
    update 
        queued_message
    set 
        status='IN_PROGRESS'
    where
        id in (
            select
                id
            from
                queued_message
            where
                status='SUBMITTED' and queue='BACKFILL_REQUEST'
            order by 
                id asc
            limit 1
        )
    returning *;
$$;

select * from set_in_progress();
于 2013-01-31T21:39:28.813 回答