在函数POSTGRESQL中锁定行

时间:2018-08-03 14:05:11

标签: postgresql transactions

我正在尝试模拟“ nextval”功能,我需要根据特定ID生成的下一个值。在某些情况下,该函数将返回相同的值。

CREATE OR REPLACE FUNCTION public.nextvalue(character,integer) 
RETURNS integer AS
$BODY$
    DECLARE
    p_id ALIAS FOR $1;
    p_numero integer;
    BEGIN

        p_numero = (SELECT numero FROM "TnextValue" WHERE id = p_id FOR UPDATE);

        IF p_numero is null THEN
            INSERT INTO "TnextValue" (numero,id) VALUES (1,p_id);
            p_numero = 1;
        END IF;

        UPDATE "TnextValue" SET numero = p_numero + 1 where id = p_id;

        RETURN p_numero;

    END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

我尝试添加FOR UPDATE语句,但问题仍然存在。我认为应该在策略(SELECT)上方添加一行

LOCK TABLE "TnextValue" IN ROW EXCLUSIVE MODE;

但是我认为这行会阻塞其他ID的表,同时获得下一个值。

谢谢!

1 个答案:

答案 0 :(得分:0)

    IF p_numero is null THEN
        INSERT INTO "TnextValue" (numero,id) VALUES (1,p_id);
        p_numero = 1;
    END IF;

不起作用,如果两个调用者想要相同的新序列,则该行没有锁定。

    IF p_numero is null THEN
        BEGIN
            INSERT INTO "TnextValue" (numero,id) VALUES (1,p_id);
            p_numero = 1;
        EXCEPTION WHEN UNIQUE_VIOLATION THEN
            RETURN public.nextvalue($1,$2);
        END;
    END IF;