Ваш код так сильно урезан, что больше не имеет смысла.
Однако вы должны блокировать таблицу только один раз, а не на каждой итерации цикла. Кроме того, вы не можете использовать commit
в функции в Postgres, поэтому вы должны также удалить это. Это также плохой стиль кодирования (в Postgres и Oracle), чтобы не предоставлять имена столбцов для оператора вставки.
Немедленное решение:
CREATE OR REPLACE FUNCTION ...
RETURNS VOID AS
$$
BEGIN
LOCK TABLE Employee1 IN EXCLUSIVE MODE;
FOR I IN 1..5 LOOP
INSERT INTO Employee1 (id, name)
VALUES (i,'test');
END LOOP;
-- no commit here!
END;
$$ LANGUAGE PLPGSQL
Вышесказанное излишне сложно в Postgres и может быть реализовано намного более эффективно без цикла:
CREATE OR REPLACE FUNCTION ....
RETURNS VOID AS
$$
BEGIN
LOCK TABLE Employee1 IN EXCLUSIVE MODE;
INSERT INTO Employee1 (id, name)
select i, test
from generate_series(1,5);
END;
$$ LANGUAGE PLPGSQL
Блокировка таблицы в монопольном режиме кажется плохой идеей для начала. В Oracle также, но в Postgres это может иметь более серьезных последствий . Если вы хотите предотвратить дублирование в таблице, создайте уникальный индекс (или ограничение) и устраните ошибки. Или используйте insert ... on conflict
в Postgres. Это будет намного более эффективно (и масштабируемо), чем блокировка полной таблицы.
Дополнительно: LOCK TABLE IN EXCLUSIVE MODE;
ведет себя по-разному в Oracle и Postgres. Хотя Oracle по-прежнему будет разрешать запросы только для чтения к этой таблице, вы блокируете каждый доступ к ней в Postgres - , включая операторы SELECT.