Блокировка и одновременное выполнение хранимой процедуры - PullRequest
1 голос
/ 24 ноября 2011

У меня есть хранимая процедура, которая выполняется удаленными клиентами на постоянной основе. Из прочтения документов у меня сложилось впечатление, что при правильной технике блокировки мне не нужно управлять этими клиентами извне, и я могу свободно запускать их так часто и одновременно, как они хотят.

Эта процедура обновляет и вставляет в несколько таблиц. Схема процедуры ниже:

LOCK TABLE table1 IN EXCLUSIVE MODE;

LOOP
    UPDATE table1 SET "var1"="var1"+1, WHERE "var2"=var2;
    IF found THEN
        EXIT;
    END IF; 

    BEGIN
        INSERT INTO table1 ("col") VALUES (1) RETURNING "ID" INTO id;
        EXIT;
    EXCEPTION WHEN unique_violation THEN
        EXIT;
    END;
    EXIT;
END LOOP;

LOCK TABLE table2 IN EXCLUSIVE MODE;

LOOP
    BEGIN
        INSERT INTO table2 ("var3","var4") values (var3,var4);
        EXIT;
    EXCEPTION WHEN unique_violation THEN
        EXIT;
    END;
END LOOP;

Существует также третья таблица после этого, которая блокируется и обновляется / вставляется так же, как таблица1. Все работает как есть, однако веб-приложение также выполняет некоторые операторы медленного выбора для одних и тех же таблиц, и исключительные блокировки время от времени вызывают большие задержки. Я понимаю, что исключительная блокировка не должна быть необходимой, однако, бесчисленное множество типов блокировок и какие из них применять к каким таблицам в моей процедуре немного сбивают с толку, поэтому я пошел на такой подход, чтобы все заработало как можно скорее.

У меня есть несколько вопросов:

Какова наилучшая стратегия блокировки для этой процедуры? Я хотел бы сделать это правильно, избегая исключительных блокировок, где я могу позволить веб-приложению запускать выборки без помех.

С какими ограничениями я буду сталкиваться по мере роста числа клиентов? Было бы лучше полностью отказаться от этого подхода и отправить данные от всех клиентов в центральное место и только запустить процедуру оттуда?

1 Ответ

4 голосов
/ 24 ноября 2011

Позвольте базе данных обрабатывать блокировку для вас. PostgreSQL, как и любая другая база данных, имеет код блокировки, который будет блокировать соответствующие строки для модификации по мере необходимости. PostgreSQL использует нечто, называемое Multi-Version Concurrency Control , что фактически означает, что читатели никогда не будут блокировать или блокироваться писателями.

С вашим текущим решением по мере роста числа клиентов вы будете увеличивать блокировку, пока ваше приложение не станет полностью непригодным для использования. Опять же, позвольте базе данных управлять блокировками для вас - она ​​очень эффективна для разрешения блокировок по мере необходимости.

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