Hibernate序列生成非连续值

che*_*ine 1 java oracle hibernate

我正在使用hibernate sequencegenerator为我的主键列自动生成唯一值.示例代码如下所示.

@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
}
Run Code Online (Sandbox Code Playgroud)

除了生成的值是交错的这一事实外,一切正常.例如,它插入5000到5015(15个插入)的值,然后第16个插入产生的值为5100.然后它适用于一些后续插入并再次出现问题.我没有任何问题,只要生成的值是唯一的,但只是好奇知道是什么原因造成的.仅供参考,我正在使用Oracle.

gpe*_*che 9

Oracle序列以这种方式工作.它们只保证唯一性,但它们不保证连续值,因为它会妨碍并行性.

他们在内部执行的操作或多或少是这样的:当您请求序列中的下一个值时,Oracle会预先计算一大块值(在您的情况下为5000-5099)并将其放入序列缓存中,然后设置seq.nextval = 5100在磁盘上.但是,如果由于活动,db必须从缓存中丢弃你的一大块值,那么当下次访问seq.nextval时,它将需要另一个块5100-5199.也就是说,Oracle甚至不会尝试保存已放入缓存的序列值.

这一点的意思是序列缓存是一种内存结构,它比序列本身更快,更可并行化,这是一种磁盘上的结构.由于我们想要扩展,我们希望避免尽可能多地访问磁盘.

您可以使用序列DDL中的CACHE子句控制给定序列的块大小:

CREATE SEQUENCE seq2
CACHE 50;
Run Code Online (Sandbox Code Playgroud)

  • 没有最佳的"CACHE"尺寸.较小的`CACHE`值会影响性能,因为Oracle必须更频繁地使用磁盘/缓冲区缓存.但真正的打击是并行性,因为从缓存中获取序列值比从序列中直接获取它们更加可并行化.`CACHE`的默认值是20,它往往*太低*.对于相当繁忙的序列,您至少需要数百个.但是,和往常一样,**首先测量**.另请参阅http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:6393918681776/thread.jspa?threadID=552069 (2认同)