Общий счетчик БД

#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;