Hibernate последовательность генерирует неконтинуальные значения - PullRequest
1 голос
/ 02 сентября 2010

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

@Entity
@Table(name = "REQUEST")
@javax.persistence.SequenceGenerator(name = "REQ_SEQ", sequenceName = "REQUEST_SEQ")
public class Request {
/**
 * Unique id for this request
 */
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "REQ_SEQ")
@Column(name = "REQ_ID")
private long requestId;
   //So on
}

Все работает нормально, за исключением того, что сгенерированные значения чередуются. Например, он вставляет значения от 5000 до 5015 (15 вставок), а затем 16-я вставка выдает значение как 5100. Затем оно работает нормально для нескольких последующих вставок и снова проблема. У меня нет никаких проблем, если сгенерированные значения уникальны, но просто интересно узнать, что может быть причиной этого. К вашему сведению, я использую Oracle.

Ответы [ 2 ]

9 голосов
/ 02 сентября 2010

Последовательности Oracle работают таким образом. Они только гарантируют уникальность, но не гарантируют последовательные значения, поскольку это препятствует параллелизму.

То, что они делают внутренне, более или менее таково: когда вы запрашиваете следующее значение в последовательности, Oracle предварительно вычисляет кусок значений (в вашем случае 5000-5099) и помещает его в кеш последовательности, а затем устанавливает seq. nextval = 5100 на диске. Но если из-за активности БД должен отбросить вашу порцию значений из кэша, при следующем обращении к seq.nextval потребуется еще одна порция 5100-5199. То есть Oracle даже не будет пытаться сохранить значения последовательности, которые были помещены в кеш.

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

Вы можете контролировать размер порции для данной последовательности, используя предложение CACHE в вашей последовательности DDL:

CREATE SEQUENCE seq2
CACHE 50;
0 голосов
/ 28 января 2015

Из документа Oracle:

CREATE SEQUENCE customers_seq
  START WITH    1000
  INCREMENT BY  1
  NOCACHE;

Ключевое слово NOCACHE - это то, что вы можете использовать, если хотите получить последовательную серию идентификаторов.Конечно, как объяснялось в предыдущих комментариях, это ограничит пропускную способность последовательности и может снизить производительность вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...