У меня есть таблица ContentAddressedFiles
, где комбинация столбцов hash
, size
и extension
- UNIQUE
. Я хочу создать хранимую процедуру, которая при вызове вставляет новую запись в таблицу с указанными значениями. Если запись для этих значений уже существует, я хочу просто вернуть эту существующую запись. Вот мой подход:Невозможно ВЫБРАТЬ причину УНИКАЛЬНОГО НАРУШЕНИЯ
CREATE OR REPLACE FUNCTION INIT_CAF(id_in_case_of_new UUID, _hash VARCHAR(255), _size INTEGER, _extension VARCHAR(255), _mimeType VARCHAR(255))
RETURNS "ContentAddressedFiles"
AS $$
DECLARE
caf "ContentAddressedFiles"%ROWTYPE;
BEGIN
INSERT INTO "ContentAddressedFiles" (id, hash, size, extension, "mimeType", "createdAt", "updatedAt")
VALUES(id_in_case_of_new, _hash, _size, _extension, _mimeType, NOW(), NOW()) RETURNING * INTO caf;
RETURN caf;
EXCEPTION WHEN unique_violation THEN
SELECT * FROM "ContentAddressedFiles" INTO caf WHERE "hash" = _hash AND "size" = _size AND "extension" = _extension;
IF NOT FOUND THEN
RAISE EXCEPTION 'This should never happen.';
END IF;
RETURN caf;
END;
$$ LANGUAGE plpgsql;
Однако, когда я вызвать процедуру из параллельных транзакций, я постоянно получаю исключение:
EXCEPTION: This should never happen.
Как это возможно? Процедура не кажется, чтобы быть в состоянии SELECT
причину провала попытки INSERT
раньше (это не id
, что столкновения, это просто кортеж <hash, size, extension>
так что вы видите поднятый exveption и нуль вместо ожидаемой строки? .. пожалуйста, добавьте выход у вас есть на вопрос –
Да, именно я получаю исключение при запуске процедуры одновременно с различных операций. – DeX3
http://stackoverflow.com/questions/6722344/select-or-insert-a-row-in-one-command –