2013-02-08 3 views
1

Допустим, я написал функцию plpgsql, которая делает следующее:Таблица блокировки в функции 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

Я бы не использовал временную таблицу для этого. Я бы не удивился, если бы один (большой) SELECT был быстрее. Вы исходите из фона SQL Server? –

+0

@a_horse_with_no_name Мой вопрос является небольшим примером и не является представителем нашего реального кода. Причина, по которой мы используем временные таблицы, выходит за рамки этого вопроса. –

ответ

3

Если вы одновременно вызываете функцию дважды, это означает, что вы используете два отдельных сеанса для этого. Временные таблицы не разделяются между сеансами, поэтому второй сеанс не будет «видеть» tmp_foobar с первого сеанса, и взаимодействия не будет. См. http://www.postgresql.org/docs/9.2/static/sql-createtable.html#AEN70605 («Временные таблицы»).

Замки сохраняются до конца транзакции (независимо от того, как вы получаете их,. Исключением являются консультативными замки, но это не то, что вы делаете)

второй вопрос не нужен ответ, потому что предпосылка ложна.

Еще одна вещь. Возможно, было бы полезно создавать индексы на вашей временной таблице и ANALYZE it; что может привести к тому, что окончательный запрос будет быстрее.

Смежные вопросы