Postgres Блокировка таблицы внутри функции не работает? - PullRequest
0 голосов
/ 05 сентября 2018
CREATE OR REPLACE FUNCTION() 
RETURND VOID AS

BEGIN

FOR I IN 1..5
LOOP
LOCK TABLE tbl_Employee1 IN EXCLUSIVE MODE;
INSERT INTO tbl_Employee1
VALUES 
(i,'test');

END LOOP;

COMMIT;

END;
$$ LANGUAGE PLPGSQL

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

1 Ответ

0 голосов
/ 05 сентября 2018

Ваш код так сильно урезан, что больше не имеет смысла.

Однако вы должны блокировать таблицу только один раз, а не на каждой итерации цикла. Кроме того, вы не можете использовать 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.

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