Oracle DB + Hibernate 中的奇怪序列顺序

Posted

技术标签:

【中文标题】Oracle DB + Hibernate 中的奇怪序列顺序【英文标题】:Weird order of sequence in Oracle DB + Hibernate 【发布时间】:2016-02-11 17:41:18 【问题描述】:

实体类的Hibernate注解如下:

@Entity
@Table(name = "MY_ENTRY")
@SequenceGenerator(name="SEQ_MY_ENTRY_ID", allocationSize=1, sequenceName="SEQ_MY_ENTRY_ID")
public class MyEntry 

@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_MY_ENTRY_ID")
private Long id;

...

Oracle DB 的 SQL 如下所示:

CREATE SEQUENCE  "SEQ_MY_ENTRY_ID" MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 1541 CACHE 20 NOORDER  NOCYCLE;

效果很好!

我只是想知道为什么生成的 ID 似乎顺序混乱。我期待像1148, 1149, 1150, ... 这样的东西。但相反,我得到例如这个:1148, 1165, 1166, 1181, 1167, 1149, 1150, 1182, 1151, 1168, 1152, 1153, 1183, 1154, ...。再次,它工作正常。它永远不会导致冲突。但是为什么会有这个奇怪的顺序呢?

【问题讨论】:

Oracle sequence caching的可能重复 你在做 RAC 吗? @mustaccio 我认为这无关。我的序列中没有任何间隙。 @MarmiteBomber 实际上我不知道我们的 Oracle DB 运行在什么之上。 " 期望类似 1148, 1149, 1150" 但您却得到 "this 1148, 1165, 1166, 1181" -- 如果你的问题不是关于差距,那么它是关于什么的? 【参考方案1】:

您描述的行为,即无序 ID 表明您已连接到 RAC 数据库。

您可以通过查询验证这一点

select name, value from v$parameter where name='cluster_database'; 

如果 VALUE 为 TRUE,则您已连接到 RAC。在这种情况下,每个实例分配其自己的缓存间隔,并根据调用 NEXTVAL 的实例返回不同的范围。因此,如果您有两个实例,第一个缓存为 1 到 20,第二个缓存为 21 到 40,您可能会得到例如1,2,21,3,4,22,23,...

查看序列的属性ORDER_FLAG

select SEQUENCE_NAME, ORDER_FLAG from user_sequences;

您很可能会看到“N”。

您可以将序列设置为ORDER 分配来抑制这种无序分配,但要做好准备,它也会有效地抑制缓存(并可能导致争用)。

 alter sequence seq1 order;

其他信息here 和here

【讨论】:

谢谢你Marmite!不幸的是,我无法在星期一之前检查它。 我的架构师确认我们使用的是 RAC 集群。您的解释对我来说很有意义,尽管查询 select name, value from v$parameter where name='cluster_database'; 只是导致了一个错误。但我可能没有***.com/questions/14924681/… 中解释的权利。

以上是关于Oracle DB + Hibernate 中的奇怪序列顺序的主要内容,如果未能解决你的问题,请参考以下文章

基于外键的增量字段(JPA、Hibernate、Oracle DB)

hibernate连接到db的方式和简单的java程序的方式有区别吗?

如何避免两个不同的线程从DB中读取相同的行(Hibernate和Oracle 10g)

DB2ORACLE SQL写法的主要区别

Hibernate不同DB的日期查询

org.hibernate.exception.ConstraintViolationException:无法更新 - DB 中的自动增量列为 NULL