Ваша функция небезопасна, поскольку возможна одновременная транзакция, которую
запущена до того, как ваша INSERT
еще не былазавершается, когда выполняется проверка IF EXISTS
вставляет конфликтующую строку
Тогда вы получите непреднамеренный дубликат.
Вы можете превратить SELECT
в SELECT ... FOR UPDATE
, чтобы уменьшить окно для состояния гонки, но вы не сможете закрыть его, если не используете SERIALIZABLE
уровень изоляции транзакции.
и функциюне защищает вас от того, что кто-то потом вставит дубликат для значения, которое вам не нужно.
Возможно, триггер BEFORE
и сериализуемые транзакции - лучший способ сделать это.