#postgresql #spring-boot
#postgresql #весенняя загрузка
Вопрос:
Я хотел бы реализовать решение, в котором моя версия будет увеличиваться на 1 для каждого типа данных при сохранении в БД, и это будет потокобезопасно.
Мои идеи: Идея 1: я создал 2 последовательности type1_seq и type2_seq, и я использовал функцию nextVal(), но nextVal никогда не откатывается в случае исключения, поэтому иногда у меня был пробел в моем счетчике, например, 1,2,4.
Идея 2: перед сохранением новой записи я должен использовать запрос (например, findMaxVersionByDataType()), чтобы получить максимальную версию по типу данных и увеличить ее на 1, но это небезопасно для потоков. Оптимистичная блокировка в этом случае бесполезна, я думаю, потому что, насколько я понимаю, мне нужно блокировать сохранение записей другими потоками в окне времени сразу после вызова findMaxVersionByDataType() до сохранения записи моим потоком.
Знаете ли вы какое-нибудь хорошее решение для повышения производительности?
Комментарии:
1. Используйте идею 2 с уникальным ограничением на (data_type, version). Нарушения уникальности предотвратят двойное сохранение одной и той же версии для одного и того же типа данных. В коде вашего приложения отловите нарушение уникальности и повторите попытку (в новой транзакции, так как вам нужно будет просмотреть недавно сохраненную строку для вашего max 1, чтобы сделать все правильно).
Ответ №1:
Не существует хорошего решения по производительности для последовательности без пробелов. Как минимум, вам нужно сохранить последовательность в таблице и заблокировать строку (или таблицу) при каждом доступе до фиксации транзакции. Пробелы являются нормальными и ожидаемыми для последовательностей. Лучше всего привыкнуть, принять это и двигаться дальше. Вы, конечно, можете создать представление, которое получает версию «на лету». Смотрите пример.
create view type_view as
select id, type_cd, row_number() over (partition by type_cd) as version
from type_data
order by id;