表锁定在plpgsql函数中

时间:2013-02-08 18:30:36

标签: postgresql plpgsql postgresql-9.2 table-locking

假设我写了plpgsql函数,它执行以下操作:

CREATE OR REPLACE FUNCTION foobar (_foo_data_id bigint)
RETURNS bigint AS $$
BEGIN

    DROP TABLE IF EXISTS tmp_foobar;

    CREATE TEMP TABLE tmp_foobar AS
    SELECT *
    FROM foo_table ft
    WHERE ft.foo_data_id = _foo_data_id;

    -- more SELECT queries on unrelated tables

    -- a final SELECT query that invokes tmp_foobar

END;

第一个问题:

如果我同时调用此函数两次,foobar()的第二次调用是否可以在tmp_foobar的第一次调用仍在运行时删除foobar()表?

我理解SELECT语句会创建一个ACCESS SHARE锁定,但锁定会持续到SELECT语句完成或直到函数末尾的隐含COMMIT为止?

第二个问题:

如果后者为真,那么foobar()的第二次调用是否会无限期地重新尝试DROP TABLE IF EXISTS tmp_foobar;,直到锁被丢弃或者在某个时刻失败?

1 个答案:

答案 0 :(得分:3)

如果您同时调用一个函数两次,则表示您正在使用两个单独的会话来执行此操作。会话之间不共享临时表,因此第二个会话不会从第一个会话中“看到”tmp_foobar,并且不会进行任何交互。请参阅http://www.postgresql.org/docs/9.2/static/sql-createtable.html#AEN70605(“临时表”)。

锁定一直持续到事务结束(无论你如何获取它们;例外是咨询锁定,但这不是你正在做的事情。)

第二个问题不需要答案,因为前提是错误的。

还有一件事。在您的临时表上创建索引并对其进行分析可能很有用;这可能会导致最终查询更快。