开发者

Hibernate sequence generates non-continous values

开发者 https://www.devze.com 2023-01-15 00:34 出处:网络
I am using a hibernate sequencegenerator to auto-generate unique values for my primary key column.The sample code is given below.

I am using a hibernate sequencegenerator to auto-generate unique values for my primary key column.The sample code is given below.

@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
}

Everything works fine except the fact that the generated values are interleaved. For example it inserts values from 5000 to 5015(15 inserts) a开发者_如何学JAVAnd then the 16th insert produces the value as 5100.Then it works fine for a few subsequent inserts and again the problem. I dont have any problem as long as the generated values are unique but just curious to know what could be causing this. FYI, I am using Oracle.


Oracle sequences work that way. They only guarantee uniqueness but they do not guarantee consecutive values as it would hamper parallelism.

What they do internally is more or less this: when you request the next value in the sequence, Oracle precomputes a chunk of values (in your case 5000-5099) and puts it in a sequence cache, and then sets seq.nextval = 5100 on disk. But if, due to activity, the db has to discard your chunk of values from the cache, when seq.nextval is accessed the next time, it will take another chunk 5100-5199. That is, Oracle will not even try to save sequence values that have been put into cache.

The point of this is that the sequence cache is a memory structure that is faster and more parallelizable that the sequence itself, which is an on-disk structure. As we want to scale up, we want to avoid going to disk as much as possible.

You can control chunk size for a given sequence using the CACHE clause in your sequence DDL:

CREATE SEQUENCE seq2
CACHE 50;


From the Oracle doc:

CREATE SEQUENCE customers_seq
  START WITH    1000
  INCREMENT BY  1
  NOCACHE;

The NOCACHE keyword is what you can use if you would like consequential series of IDs. Of course as explained in previous comments, that would limit the sequence throughput and may hinder your application performance.

0

精彩评论

暂无评论...
验证码 换一张
取 消