Nano Hash - криптовалюты, майнинг, программирование

Спящий режим и странное поведение с последовательностями DB2

Я использую Hibernate с Spring и DB2. Я использую последовательности для генерации первичного ключа для сущностей. Все объекты используют одну и ту же последовательность HIBERNATE_SEQUENCE, которая используется по умолчанию в спящем режиме.

Проблема в том, что значения, которые попадают в первичные ключи, примерно в 10 раз выше значений, возвращаемых HIBERNATE_SEQUENCE.

Например, эта ситуация сразу после вставки новой строки в таблицу:

select max(id) as primary_key, nextval for hibernate_sequence sequence_value from tbl ;

primary_key sequence_value
501483661   50148373

Я сопоставил первичный ключ, как это, в суперклассе для всех сущностей:

@MappedSuperclass
public class AbstractEntity implements Serializable {
   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE)
   private Integer id;

Я бы хотел, чтобы спящий режим использовал те значения, которые он извлекает из последовательности, а не значения последовательности, умноженные на 10. Как правильно это сделать?


Ответы:


1

Hibernate, похоже, делает следующее:

Когда спящему режиму требуется первичный ключ, он извлекает значение из последовательности. Hibernate сгенерирует несколько значений первичного ключа из одного значения последовательности. Например, hibernate будет хранить внутренний счетчик, значение которого добавляется к значению последовательности для получения значения первичного ключа. Когда внутренний счетчик достигает своего предела, счетчик сбрасывается, из последовательности получается новое значение, и процесс первичного ключа начинается заново.

Например:

  1. Значение, полученное из последовательности, равно 123. Полученное значение последовательности сохраняется для каждого сеанса.
  2. Для текущего сеанса сгенерированы первичные ключи: 1230, 1231, 1232, 1233, ..., 1238, 1239. Значение счетчика объединяется со значением последовательности, полученным на шаге 1. При необходимости генерируется ключ.
  3. Теперь процесс генерации первичного ключа начинается заново. Перейти к 1.

Это вызывает следующие эффекты:

  • значение последовательности базы данных эффективно умножается на 10
  • Hibernate не нужно читать базу данных для каждой вставки БД, которую он делает. Приведенный выше алгоритм сокращает количество операций чтения последовательности до 10 % (при выполнении большого количества вставок за один сеанс).
  • каждое другое приложение, не находящееся в спящем режиме, должно использовать аналогичный алгоритм для генерации первичных ключей из последовательности, иначе в какой-то момент возникнут конфликты первичных ключей.

Чтобы заставить спящий режим использовать фактические значения, полученные из последовательности, можно использовать это сопоставление:

@Id
@GeneratedValue(generator="hibernate_sequence")
@GenericGenerator(strategy="sequence", name="hibernate_sequence")
private Integer id;
15.02.2010

2

В команде DB2 create sequence есть несколько параметров, которые могут повлиять на это. INCREMENT_BY говорит, насколько увеличивать значение при каждом вызове nextval. CACHE с NO_ORDER резервирует определенное количество значений, поэтому, если несколько соединений используют одну и ту же последовательность, они могут получать значения быстрее за счет того, что значения не по порядку. Я бы проверил, как была создана последовательность, прежде чем копаться в Hibernate. Глядя на код Hibernate, это довольно просто - посмотрите на DB2Dialect, и вы увидите, какой sql он использует для получения значения последовательности.

11.02.2010

3

Я решил эту проблему, установив allocationSize в 1 в аннотации @SequenceGenerator.

Пример:

@MappedSuperclass
public class AbstractEntity implements Serializable {
   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GENERATOR")
   private Integer id;

и сущность:

@SequenceGenerator(name = "SEQ_GENERATOR", sequenceName = "MY_SEQUENCE", allocationSize = 1)
public class MyEntity extends AbstractEntity {
28.05.2014
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..