Postgresql函数,它锁定表,更新值并返回行

时间:2016-08-29 15:04:56

标签: postgresql

对于我的Hi / Lo实现,我需要一个获取独占表锁,更新值并选择一行的函数。我想出了以下代码:

CREATE OR REPLACE FUNCTION bb_next_hi(tbl varchar(35))  
RETURNS setof record AS
$$ 
    LOCK TABLE hilo IN ACCESS EXCLUSIVE MODE;
    OPEN ref FOR SELECT hi as "Hi", lo as "Lo", "table" as "Table" FROM hilo WHERE "table" = $1;
    UPDATE hilo SET hi = hi + 1 WHERE "table" = $1
    RETURN ref;

$$ LANGUAGE plpgsql;

但是,在调用该函数时,它不返回一行,而是返回一个内容类似于"未命名的门户3"的列。我想我应该迭代返回的ref(但是如何)?

我可以使用的另一种方法是使用UPDATE RETURNING语句,但我不确定在这种情况下是否会出现竞争条件。任何帮助,将不胜感激。感谢

2 个答案:

答案 0 :(得分:2)

这对我来说似乎更简单:

CREATE OR REPLACE FUNCTION bb_next_hi(tbl varchar(35))  
RETURNS setof record AS
$$ 
BEGIN
    LOCK TABLE hilo IN ACCESS EXCLUSIVE MODE;
    RETURN QUERY UPDATE hilo SET hi = hi + 1 WHERE "table" = $1
        RETURNING hi as "Hi", lo as "Lo", "table" as "Table";
END;
$$ LANGUAGE plpgsql;

我通常也会定义RETURNS TABLE (col1 varchar, col2 varchar...)而不是RETURNS setof record

答案 1 :(得分:1)

您正在使用cursor变量(您没有声明,并且缺少其他一些PL / pgSQL必需元素)并且您返回该变量。游标引用确实被称为"门户网站"这样就解释了你的输出。更好的方法是:

CREATE OR REPLACE FUNCTION bb_next_hi(tbl varchar(35))  
RETURNS TABLE ("Hi" int, "Lo" int, "Table" varchar(35)) AS $$
BEGIN
    LOCK TABLE hilo IN ACCESS EXCLUSIVE MODE;
    RETURN QUERY SELECT hi, lo, $1 FROM hilo WHERE "table" = $1;
    UPDATE hilo SET hi = hi + 1 WHERE "table" = $1;
    RETURN;
END;
$$ LANGUAGE plpgsql STRICT;

但你真的需要一张独家锁吗?获取一致的表快照的入侵方法要少得多。