如何在pgsql函数调用期间锁定(独占)记录?

时间:2014-11-11 14:12:57

标签: postgresql

pgsql中,如何在函数运行期间锁定记录?考虑以下功能。

create or replace function foo.bar_func(int)returns int as $$

with s as (select * from foo.bar where id=$1);--  <--lock the fetched row [BEGIN]
/*
Some query, update, insert, ...
*/
select coalesce(s.id,-1) from s;--return something.
-- <-- release the locked row [END]
$$ language sql;

我喜欢在功能开始时锁定行(如果找到),直到完成其工作。

pg_advisory_lock(bigint)如何运作?这有帮助吗?与select for update有什么不同?

1 个答案:

答案 0 :(得分:1)

SELECT … FOR UPDATE执行您期望的操作,即将返回的行专门锁定,直到当前事务结束(see here)。

另一方面,咨询锁是应用程序定义的。它们被保留到当前事务结束或直到当前会话结束(see here)。因此,需要手动检查它们,您可能需要手动释放它们。

如果要在示例代码中使用变量(如s),则必须使用PL / pgSQL。但是,似乎没有办法使您的函数具有事务性。相反,它将始终在周围事务的上下文中执行。向函数添加EXCEPTION子句会导致函数包含在子事务(see here)中,但函数获取的锁将保留到周围事务结束。我用PG 9.3进行了测试。