У меня есть следующая таблица:Postgres: как добавить уникальный идентификатор в таблице
CREATE TABLE myid
(
nid bigserial NOT NULL,
myid character varying NOT NULL,
CONSTRAINT myid_pkey PRIMARY KEY (myid)
)
Теперь я хочу, чтобы добавить записи в эту таблицу с помощью следующей функции:
CREATE FUNCTION getmyid(_myid character varying)
RETURNS bigint AS
$BODY$ --version 1.1 2015-03-04 08:16
DECLARE
p_nid bigint;
BEGIN
SELECT nid INTO p_nid FROM myid WHERE myid=_myid FOR UPDATE;
IF NOT FOUND THEN
INSERT INTO myid(myid) VALUES(_myid) RETURNING nid INTO p_nid;
END IF;
RETURN p_nid;
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Обычно это работает отлично, но при высокой нагрузке эта функция иногда терпит неудачу, поскольку «дублирующее значение ключа нарушает уникальное ограничение» myid_pkey »; Эта функция вызывается из триггера при вставке в другую таблицу, а вставки вызывается внутри транзакции. Уровень изоляции установлен для READ COMMITED , postgres 9.1 на Debian Wheezy. Что я делаю неправильно?
Почему * если *? Что не так с 'INSERT INTO myid (myid) VALUES (_myid) ГДЕ НЕ СУЩЕСТВУЕТ (SELECT 1 FROM myid WHERE myid = _myid);'? [можно сделать в простом SQL, без необходимости в plpgsql] – wildplasser
@wildplasser Я собирался прокомментировать то же :) –
@wildplasser: это все равно может привести к «дублированию значения ключа», если две сессии делают это точно в том же (но я согласен, что это более эффективно) –