Стоит ли параллельно/параллельно ВСТАВЛЯТЬ В… (ВЫБЕРИТЕ…) в ту же таблицу в Postgres?

#postgresql #concurrency #transactions #plpgsql

Вопрос:

Я пытался ВСТАВИТЬ В…. ( ВЫБРАТЬ… ) (вставка пакета строк из подзапроса ВЫБРАТЬ…) в ту же таблицу в моей базе данных. По большей части это работало, однако время от времени я видел, как регистрировалось исключение «Тупик». Имеет ли смысл это делать или есть способ избежать тупикового сценария? На высоком уровне мои запросы оба похожи на эту структуру:

 CREATE OR REPLACE PROCEDURE myConcurrentProc() LANGUAGE plpgsql AS $procedure$ DECLARE BEGIN  LOOP  EXIT WHEN row_count = 0   WITH cte AS (SELECT *  FROM TableA tbla  WHERE EXISTS (SELECT 1 FROM TableB tblb WHERE tblb.id = tbla.id)  INSERT INTO concurrent_table (SELECT id FROM cte);   COMMIT;   UPDATE log_tbl  SET status = 'FINISHED',  WHERE job_name = 'tblA_and_B_job';   END LOOP; END $procedure$;  

И другой скрипт, который выполняется параллельно и ВСТАВЛЯЕТ… также в ту же таблицу, также в основном:

 CREATE OR REPLACE PROCEDURE myConcurrentProc() LANGUAGE plpgsql AS $procedure$ DECLARE BEGIN  LOOP  EXIT WHEN row_count = 0   WITH cte AS (SELECT *  FROM TableC c  WHERE EXISTS (SELECT 1 FROM TableD d WHERE d.id = tblc.id)  INSERT INTO concurrent_table (SELECT id FROM cte);   COMMIT;   UPDATE log_tbl  SET status = 'FINISHED',  WHERE job_name = 'tbl_C_and_D_job';   END LOOP; END $procedure$;  

Таким образом, вы можете видеть, что я запрашиваю две разные таблицы в каждом сценарии, однако вставляю их в одну и ту же some_table . У меня также есть инструкция UPDATE…, которая записывает данные в таблицу журнала, поэтому я полагаю, что это также может вызвать проблемы. Есть ли какой-нибудь способ использовать BEGIN… ЗАКОНЧИТЕ здесь и ЗАФИКСИРУЙТЕ, чтобы избежать каких-либо проблем с взаимоблокировкой/параллелизмом, или мне следует просто создать 2-ю таблицу для хранения данных «tbl_C_and_D_job»?

Комментарии:

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

2. Ваш пример кода синтаксически некорректен по нескольким причинам. Это затрудняет понимание того, что делает ваш реальный код.