Database 是否允许标记为稳定的PostgreSQL函数获取锁?
PostgreSQL文档在将函数标记为稳定函数这一主题上有这样的表述: 稳定表示函数无法修改数据库,并且 在单个表扫描中,它将始终返回相同的值 相同参数值的结果,但其结果可能会更改 跨越SQL语句。这是功能的适当选择 其结果取决于数据库查找、参数变量(如 当前时区)等(不适用于AFTER触发器 希望查询由当前命令修改的行。)另请注意 当前函数的_时间戳系列符合稳定条件, 因为它们的值在事务中不会更改 我有一个函数(称之为Database 是否允许标记为稳定的PostgreSQL函数获取锁?,database,postgresql,stored-procedures,plpgsql,Database,Postgresql,Stored Procedures,Plpgsql,PostgreSQL文档在将函数标记为稳定函数这一主题上有这样的表述: 稳定表示函数无法修改数据库,并且 在单个表扫描中,它将始终返回相同的值 相同参数值的结果,但其结果可能会更改 跨越SQL语句。这是功能的适当选择 其结果取决于数据库查找、参数变量(如 当前时区)等(不适用于AFTER触发器 希望查询由当前命令修改的行。)另请注意 当前函数的_时间戳系列符合稳定条件, 因为它们的值在事务中不会更改 我有一个函数(称之为F),它需要在启动前以独占模式锁定表,以保证在调用函数和事务结束之间不会插入
F
),它需要在启动前以独占模式锁定表,以保证在调用函数和事务结束之间不会插入新行F
不会对数据库进行任何直接更改。对于计划者来说,在同一事务中使用相同的参数省略对F
的多次调用是安全的,只要调用一次
例如,让我们使用
CREATE FUNCTION F(x INTEGER) RETURNS INTEGER AS $$
BEGIN
LOCK TABLE foobar IN EXCLUSIVE MODE;
RETURN (SELECT COUNT(*) FROM foobar WHERE id = x);
END;
$$ LANGUAGE 'plpgsql';
我的问题是,锁获取是否会取消该函数被标记为稳定的功能?也就是说,在这种情况下,获取锁是否被视为“修改数据库”
编辑以添加:使用建议锁怎么样?这会改变答案吗?嗯,这是一个简单的答案。我试过了,PG显然不高兴
ERROR: LOCK TABLE is not allowed in a non-volatile function
CONTEXT: SQL statement "LOCK TABLE foobar IN EXCLUSIVE MODE"
所以答案是肯定的,使用锁表
肯定会取消函数被标记为稳定的资格
但是,使用建议锁不会(至少,我在尝试时不会出现错误)。您可以轻松测试,这不会起作用。您将得到以下错误:
ERROR: LOCK TABLE is not allowed in a non-volatile function
但这不是问题。如果希望函数看到表的稳定快照,只需使用
START TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY;
那么这张桌子就不会为你换了