середа, 29 квітня 2009 р.

Хороша стаття про чергу завдань на PostgreSQL

Скопійовано із статі

Собственно блокировка: pg_try_advisory_lock()

Теперь модифицируем наш запрос так, чтобы при его запуске на нескольких машинах результаты никогда не пересекались. Это делается так (псевдо-операция @IDS := ... означает, что данные нужно сохранить в некоторый массив вызывающего скрипта):

/* Исходный запрос: получаем элементы-кандидаты на обработку. */
@IDS := ARRAY(
 SELECT id
 FROM subscription
 WHERE
   last_mail_at < MAILING_STARTED_AT
   AND subscription_type = <тип подписки>
   AND pg_try_advisory_lock(tableoid::INTEGER, id) /* вот она, блокировка! */
 LIMIT 100
);

/* Пост-проверка: отсеиваем тех, кто успел пометиться обработанным за */
/* время работы предыдущего запроса (см. ниже подробности про это). */
@IDS := ARRAY(
 SELECT id
 FROM subscription
 WHERE
   last_mail_at < MAILING_STARTED_AT
   AND id IN (@IDS)

);


Функция pg_try_advisory_lock() пытается "повесить" исключительную блокировку на некоторый
"виртуальный" идентификтор, который описывается парой ее параметров. Если этот идентификатор
уже заблокирован, она ничего не делает и возвращает false. Если же блокировку удалось
установить, то функция возвращает true. Блокировка снимается, когда вызывается
pg_advisory_unlock(), либо когда клиент отсоединяется от базы данных.

Немає коментарів: