postgres pg_try_advisory_lock и лимит проблем - PullRequest
1 голос
/ 02 января 2011

Как указано в http://www.postgresql.org/docs/8.2/interactive/explicit-locking.html, гарантия не будет Предел может быть применен до блокировочного ряда. Хотя оболочка над pg_try_advisory_lock должна работать, но не работать.

Следующий код блокирует только одну строку. Если тот же код выполняется из другого экземпляра, а не блокирует разблокированную строку, он пытается заблокировать первый идентификатор, который уже был заблокирован, и возвращает false.

ref: http://www.flyingtealeaf.com/2010/02/17/postgresql-concurrency
блокировка строк до следующего выбора postgres и это

select pg_try_advisory_lock(id), * 
from 
( 
  select  id,val
from test
left JOIN pg_locks pgl
       ON pgl.classid = tableoid('test')
      AND pgl.objid = test.id
      AND pgl.pid <> pg_backend_pid()

    WHERE pgl.objid IS NULL
order by id limit 1
) t

Ответы [ 2 ]

3 голосов
/ 03 января 2011

Насколько я понял, вы пытаетесь получить рекомендательную блокировку для первой строки, которая не была помечена рекомендательной блокировкой.

Редактировать: после попытки этого pg_try_advisory_lock () во внутреннем select, по-видимому, не работает (следовало подумать об этом ранее).Но простое исключение всех строк из таблицы с помощью проверки objid должно работать:

select pg_try_advisory_lock(id), * 
from 
( 
  select  id,val
  from test
  where id not in (select objid from pg_locks where locktype = 'advisory')
  order by id limit 1
) t

Редактировать

Хотя в pg_locks будут отображаться консультативные блокировки, они никогда не будут иметь никакихинформация о таблице или строке, которая была заблокирована.В конце концов, pg_advisory_lock () просто передается число, которое не имеет связи с базовой таблицей или строкой.

SELECT pg_advisory_lock(42)

создаст точно такую ​​же консультативную блокировку, что и

SELECT pg_advisory_lock(id) 
FROM foo 
WHERE id = 42

Так что ваше объединение с использованием classid никогда не будет успешным.

0 голосов
/ 03 января 2011

Извините за мою ошибку. Я должен был пройти через первую ссылку ссылка за строкой. Уловка, которую делал автор, - это просто установить classid при вызове функции блокировки. Следующий код наконец-то работает для меня с LIMIT

select pg_try_advisory_lock(tableoid('test'),id) , * from
(
select  id,val
from test
LEFT JOIN pg_locks pgl
       ON pgl.classid = tableoid('test')
      AND pgl.objid = test.id
      AND pgl.pid <> pg_backend_pid()

    WHERE pgl.objid IS NULL
order by id    limit 1)f

Табличная функция (скопировано из ссылки № 1)

CREATE OR REPLACE FUNCTION tableoid(tablename TEXT) RETURNS INTEGER AS $$
BEGIN
  RETURN (SELECT oid FROM pg_class WHERE relname = tablename);
END
$$
LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER;

Чем ты
a_horse_with_no_name за ваше время и усилия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...