假设我写了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;
,直到锁被丢弃或者在某个时刻失败?
答案 0 :(得分:3)
如果您同时调用一个函数两次,则表示您正在使用两个单独的会话来执行此操作。会话之间不共享临时表,因此第二个会话不会从第一个会话中“看到”tmp_foobar,并且不会进行任何交互。请参阅http://www.postgresql.org/docs/9.2/static/sql-createtable.html#AEN70605(“临时表”)。
锁定一直持续到事务结束(无论你如何获取它们;例外是咨询锁定,但这不是你正在做的事情。)
第二个问题不需要答案,因为前提是错误的。
还有一件事。在您的临时表上创建索引并对其进行分析可能很有用;这可能会导致最终查询更快。