Автор оригинала: Vlad Mihalcea.
Вступление
В этом посте мы раскроем генератор идентификаторов последовательности, сочетающий эффективность назначения идентификаторов и совместимость с другими внешними системами (одновременный доступ к базовой системе баз данных).
Традиционно существовали две стратегии идентификации последовательностей на выбор: последовательность
и секило Traditionally there have been two sequence identifier strategies to choose from:
sequence
Идентификатор последовательности
, всегда попадающий в базу данных для каждого нового присвоения значения. Даже с предварительным распределением последовательности баз данных у нас есть значительные затраты на доставку базы данных туда и обратно.
Идентификатор seqhilo
с использованием алгоритма hilo . Этот генератор вычисляет некоторые значения идентификаторов в памяти, что сокращает количество вызовов базы данных в оба конца. Проблема с этим методом оптимизации заключается в том, что текущее значение последовательности базы данных больше не отражает текущее наибольшее значение, сгенерированное в памяти.
Последовательность базы данных используется в качестве номера корзины, что затрудняет взаимодействие других систем с рассматриваемой таблицей базы данных. Другие приложения должны знать внутреннюю работу стратегии hilo
идентификаторов, чтобы правильно генерировать неконфликтные идентификаторы.
Расширенные идентификаторы
Hibernate предлагает новый класс генераторов идентификаторов , устраняющий многие недостатки оригинального оптимизатора hilo|/.
Новая стратегия оптимизации настраивается, и мы даже можем предоставить нашу собственную реализацию оптимизации. По умолчанию Hibernate поставляется со следующими встроенными оптимизаторами:
none
приводит к тому, что каждый идентификатор извлекается из базы данных, поэтому он эквивалентен исходному генератору последовательности .hilo
использует алгоритм hilo и это эквивалентно оригинальному секхило генератору.объединенный
использует стратегию оптимизации, подобную hilo, но самая высокая граница текущих идентификаторов в памяти извлекается из фактического значения последовательности базы данных.объединенный-lo
аналогиченобъединенному
оптимизатору но значение последовательности базы данных используется в качестве текущей нижней границы в памяти.
Основное преимущество объединенных
оптимизаторов заключается в том, что они совместимы с другими внешними системами, и это на самом деле то, что мы ищем, генератор идентификаторов, который одновременно эффективен и не конфликтует, когда другие внешние системы одновременно вставляют строки в одни и те же таблицы базы данных.
Объединенный оптимизатор
Оптимизатор объединенный
работает, как показано на следующей диаграмме.
Как вы можете видеть, даже если у нас есть внешний клиент, вставляющий строку с использованием нового значения последовательности базы данных, это не будет противоречить нашему приложению.
Для использования объединенного
оптимизатора сопоставление идентификаторов сущностей выглядит следующим образом:
@Id @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "post_sequence" ) @SequenceGenerator( name = "post_sequence", sequenceName = "post_sequence", allocationSize = 3 ) private Long id;
Объединенный оптимизатор lo
В объединенный- lo
оптимизатор аналогичен объединенному The
pooled-lo
Чтобы понять, как работает pooled-lo
, ознакомьтесь с этой диаграммой:
Чтобы использовать оптимизатор pooled-lo
, сопоставление идентификаторов сущностей будет выглядеть следующим образом:
@Id @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "pooled-lo" ) @GenericGenerator( name = "pooled-lo", strategy = "sequence", parameters = { @Parameter(name = "sequence_name", value = "post_sequence"), @Parameter(name = "initial_value", value = "1"), @Parameter(name = "increment_size", value = "3"), @Parameter(name = "optimizer", value = "pooled-lo") } )
В отличие от объединенных
, объединенных- lo
сопоставление более подробное, так как нам нужно использовать @GenericGenerator
для передачи оптимизатора
параметр, так как JPA @SequenceGenerator
не предлагает эту опцию. Более компактный @SequenceGenerator
полезен только для объединенного
генератора, поскольку Hibernate выбирает его по умолчанию, если атрибут allocationSize
больше, чем 1
.
Поскольку сопоставление @SequenceGenerator
более простое , чем использование специфичного для гибернации @GenericGenerator
, вы можете переключиться на объединенный- Ло
вместо значения по умолчанию объединенный
оптимизатор, если вы предоставляете это свойство конфигурации гибернации:
С помощью этого набора свойств вы можете использовать @SequenceGenerator
сопоставление, а Hibernate будет использовать объединенный кредит
вместо объединено
:
@Id @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "post_sequence" ) @SequenceGenerator( name = "post_sequence", sequenceName = "post_sequence", allocationSize = 3 ) private Long id;
Потрясающе, правда?
Вывод
Объединенный
и объединены- оптимизаторы lo
чрезвычайно полезны, но не все разработчики знают об их существовании. Если вы ранее использовали генератор hilo
, вы можете переключиться на объединенный
или объединенный-lo
. Ознакомьтесь с этой статьей подробнее пошаговое руководство о том, как вы можете перейти из hilo
в объединенный
оптимизатор.