Как предотвратить параллельные вызовы функций?

У меня проблема:

У меня есть функция PostgreSQL, которая выполняет FOR цикл по table_a записям и вставляет в table_b данные из обеих таблиц, и все записи связаны одним и тем же номером процесса.

Пример:

DECLARE
......

BEGIN

FOR rec in 

(select * from table_a where *some_condition*)

LOOP

some_value := (select value from table_b where some_condition_2);

insert into table_b (some_field, process) VALUES (some_value + rec.other_value, some_process);


END LOOP

COMMIT;

END;

Если я вызову эту функцию одновременно в двух сеансах, ожидаемый результат в table_a должен быть:

(process 1) record 1
(process 1) record 2
(process 1) record 3
(process 1) record 4
(process 1) record 5
(process 2) record 6
(process 2) record 7
(process 2) record 8
(process 2) record 9
(process 2) record 10

Потому что я предполагаю, что когда я вызываю функцию, все вставки должны выполняться подряд без перерыва.

Но иногда они выполняются таким образом:

(process 1) record 1
(process 1) record 2
(process 1) record 3
(process 2) record 4 (*)
(process 1) record 5
(process 2) record 6 (*)
(process 1) record 7
(process 2) record 8
(process 2) record 9
(process 2) record 10

И значение some_field в table_a неверно.

Почему это происходит?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
201
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ничто не препятствует одновременному запуску функции в нескольких сеансах и одновременному выбору и вставке данных.

Чтобы убедиться, что никакие два вызова функции не могут выполняться одновременно, лучше всего использовать рекомендательную блокировку:

CREATE FUNCTION ... AS
$$BEGIN
   PERFORM pg_advisory_lock(42);

   /* processing */

   PERFORM pg_advisory_unlock(42);
END;$$;

Ключ 42 - это число по вашему выбору.

Другие вопросы по теме

Последовательная асинхронная очередь GCD против последовательной очереди синхронизации, вложенной в асинхронную
Как понять результат увеличения и печати глобальной переменной двумя потоками?
Java-эквивалент будущего Scala?
Возможно ли в параллельном программировании, что при использовании блокировок программа может иногда использовать больше процессоров, чем необходимо?
Почему неактивная параллельная очередь блокирует полное выполнение функции?
Std::shared_ptr проверка работоспособности параллельного доступа
Является ли поток Java демоном «в том и только в том случае, если» создающий поток является демоном?
Почему эти безблокировочные реализации подсчета ссылок не взрываются (или взрываются)?
Гарантированно ли сохраняется порядок записи в отдельные члены изменчивой структуры?
Обновление логического значения в многопоточном процессе

Похожие вопросы

Pgloader не может загружать символы испанского языка
Как я могу лаконично использовать переменную SET в операторах DROP/CREATE/INSERT в PostgreSQL?
Триггер перед вставкой в ​​PostgreSQL и за исключением некоторых столбцов
Автоматически вызывать функцию после обновления материализованного представления?
Я хочу преобразовать определенный пользователем тип данных из ORACLE в рабочие данные, определенные пользователем POSTGRE?
В чем разница между пунктами «временная таблица» и «глобальная временная таблица» в postgresql?
JavaScript Sinusbot PostgreSQL\ ошибка: pq: значение слишком длинное для символьного типа (1)
Как подключить существующую внешнюю базу данных PostgreSQL для автоматического создания файла Models.py для Django Rest Framework?
Вызвать хранимую функцию postgresql в java с возвратом?
Как выбрать все строки, в которых значение нескольких столбцов встречается более одного раза в postgresql?