Возникнет ли race condition при параллельном insert postgres
Есть таблица create table if not exists objects(
obj_id bigserial primary key,
auth_id bigint references users (user_id) on delete cascade,
path ltree not null,
text text not null,
num_likes integer default 0 not null,
creation_time timestamptz default current_timestamp not null ,
modification_time timestamptz
);
и триггер
CREATE OR REPLACE FUNCTION insert_object_before_process() RETURNS trigger AS $insert_object_before_process$
BEGIN
new.path = new.path || new.obj_id::text;
return new;
END;
$insert_object_before_process$ LANGUAGE plpgsql;
CREATE TRIGGER insert_object_before_trigger
BEFORE INSERT ON objects
FOR EACH ROW EXECUTE PROCEDURE insert_object_before_process ()
который при добавлении insert into objects (auth_id, text, path) values (1, 'Привет ребята!', '1'); формирует путь из указанного пользователем + новый serial obj_id. Это нужно чтобы автоматически при ответе на комментарий генерировать новый путь ltree, так как имею древовидную структуру.
- Вопрос1: возникнет ли race condition при параллельной вставке (запрос отменится/запишется 2 раза)
- Вопрос2: Думаю насчет postgres sequence, чтобы не иметь бесполезное поле obj_id, но будет nextval потокобезопасным?
- Есть ли способ лучше?
Ответы (1 шт):
возникнет ли race condition при параллельной вставке (запрос отменится/запишется 2 раза)
Нет. Но unique всё равно добавьте к полю, раз нужна уникальность.
Думаю насчет postgres sequence, чтобы не иметь бесполезное поле obj_id, но будет nextval потокобезопасным?
Вы уже его используете. bigserial - это лишь синтаксический сахар, как раз над create sequence и bigint полем с default nextval(sequence_name). Посмотрите в pg_dump этой таблицы.
Сиквенсы специально сделаны нетранзакционными для быстрой и гарантированно уникальной генерации значений. Два nextval не могут вернуть одно и то же значение сколь бы быстро не были вызваны.