powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Сохранить в запись id предыдущей записи при конкурентном доступе
4 сообщений из 4, страница 1 из 1
Сохранить в запись id предыдущей записи при конкурентном доступе
    #39385375
=MOHAX=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
У меня есть таблица events, в которой есть поля id и prev_id (которое является уникальным и ссылается на таблицу events). Поле prev_id нужно для того, чтобы программа могла построить очередь из событий.

Для создания новой записи в events у меня используется следующая функция:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE FUNCTION sp_create_event() RETURNS bigint
    LANGUAGE plpgsql
    AS $$
DECLARE
  pevent_id bigint;
BEGIN
  LOCK TABLE events IN EXCLUSIVE MODE;
  
  INSERT INTO events(/*Куча полей*/, prev_id)
    VALUES(/*Куча полей*/, (SELECT MAX(id) FROM events))
  RETURNING id INTO pevent_id;
  
  RETURN pevent_id;
END;
$$;



Но блокировка таблицы events в EXCLUSIVE MODE негативно сказывается на производительности приложения. Можно ли как-нибудь ее избежать?

Я пробовал вариант последовательным Insert/Update, но он работает (Поле prev_id должно быть уникально, а появляются дубликаты):

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE FUNCTION sp_create_event() RETURNS bigint
    LANGUAGE plpgsql
    AS $$
DECLARE
  pevent_id bigint;
BEGIN
  INSERT INTO events(/*Куча полей*/, prev_id)
    VALUES(/*Куча полей*/, (SELECT MAX(id) FROM events))
  RETURNING id INTO pevent_id;
  
  UPDATE events
    SET prev_id = (SELECT MAX(id) FROM events WHERE id < pevent_id)
  WHERE id = pevent_id;
  
  RETURN pevent_id;
END;
$$;
...
Рейтинг: 0 / 0
Сохранить в запись id предыдущей записи при конкурентном доступе
    #39385385
=MOHAX=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я пробовал вариант последовательным Insert/Update, но он НЕ работает.
...
Рейтинг: 0 / 0
Сохранить в запись id предыдущей записи при конкурентном доступе
    #39385433
grgdvo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
=MOHAX=,

а id события нельзя заменить на сиквенс?? (sequence)
тогда всякие локи не нужны будут, каждый INSERT в event будет возвращать новый уникальный id.
...
Рейтинг: 0 / 0
Сохранить в запись id предыдущей записи при конкурентном доступе
    #39390630
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
=MOHAX=,

можно разгрузить чтение, лоча не таблицу, а строку в другой таблице, с единственным назначением--хранить достигнутое и быть ресурсом, к которому очередь.

тогда чтение ивентов будет свободным, а запись -- строго в очередь.

но, думаю, будут проблемы с параллельными транзакциями, в которых будет по несколько ивентов (надо протестить).


вообще говоря поизучайте pgq -- организацию очереди и расчёт батча -- там почти без локов, но всё не так примитивно, как хотелось бы.


я, в свое время порешал другую задачу -- из последовательно забираемых сиквенсов в т.ч. в параллельные транзы отследить максимальный, все меньшие которого закоммичены или ролбекнуты к настоящему моменту -- в дело не пошло, но работало чётко. хотя было собрано с использованием таких несинхронных штук, как pg_stat_activity.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Сохранить в запись id предыдущей записи при конкурентном доступе
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]