1

假设我编写了执行以下操作的 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;直到锁被删除还是会在某个时候失败?

4

1 回答 1

3

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

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

第二个问题不需要回答,因为前提是假的。

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

于 2013-02-08T19:38:57.057 回答