【问题标题】:Is a PostgreSQL function marked as STABLE allowed to acquire locks?标记为 STABLE 的 PostgreSQL 函数是否允许获取锁?
【发布时间】:2018-10-02 18:55:27
【问题描述】:

PostgreSQL 文档在将函数标记为 STABLE 的主题上有这样的说法:

STABLE 表示该函数不能修改数据库,并且 在单个表扫描中,它将始终返回相同的 结果相同的参数值,但其结果可能会改变 跨 SQL 语句。 This is the appropriate selection for functions 其结果取决于数据库查找、参数变量(例如 当前时区)等(不适合 AFTER 触发器 希望查询当前命令修改的行。)另请注意 current_timestamp 系列函数有资格作为稳定函数, 因为它们的值在事务中不会改变。

我有一个函数(称为F),它需要在开始之前锁定一个表IN EXCLUSIVE MODE,以保证在调用函数和事务结束之间不会插入新行。 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';

我的问题是,获取锁是否会取消该功能被标记为STABLE 的资格?也就是说,在这种情况下,获取锁是否被视为“修改数据库”?

编辑添加:使用咨询锁怎么样?这会改变答案吗?

【问题讨论】:

    标签: database postgresql stored-procedures plpgsql


    【解决方案1】:

    您可以轻松地进行测试,但这是行不通的。你会得到这个错误:

    ERROR:  LOCK TABLE is not allowed in a non-volatile function
    

    但这没问题。如果您希望您的函数看到表的稳定快照,只需使用以下命令启动事务

    START TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY;
    

    那么桌子不会为你改变。

    【讨论】:

      【解决方案2】:

      嗯,这是一个简单的答案。我试过了,PG明显不高兴。

      ERROR:  LOCK TABLE is not allowed in a non-volatile function
      CONTEXT:  SQL statement "LOCK TABLE foobar IN EXCLUSIVE MODE"
      

      所以答案是肯定的,使用LOCK TABLE 肯定会取消函数被标记为 STABLE 的资格。

      但是,使用咨询锁不会(至少,我在尝试时不会出错)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-20
        • 2015-07-03
        • 1970-01-01
        相关资源
        最近更新 更多