【问题标题】:Table locking in a plpgsql functionplpgsql 函数中的表锁定
【发布时间】:2013-01-24 14:25:53
【问题描述】:

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

【问题讨论】:

  • 一开始我不会使用临时表。如果单个(大)SELECT 更快,我不会感到惊讶。您是否具有 SQL Server 背景?
  • @a_horse_with_no_name 我的问题是一个小规模的例子,并不代表我们的真实代码。我们使用临时表的原因超出了这个问题的范围。

标签: postgresql plpgsql postgresql-9.2 table-locking


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2012-03-26
    • 2013-08-25
    • 2013-12-20
    • 2012-04-23
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多