0

postgresを使用してFIFOキューを構築し、複数のコンシューマーを持つ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;

その後、戻り値は破棄されます。begin / 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

必要な値を返す関数を作成できます。各関数はトランザクションとして実行されます。「begin;」を配置しないでください。および「コミット;」関数本体で。以下の機能はうまくいくはずです。

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 に答える