oracle序列被搞砸了,插入也因此而失败



我正在使用序列将域对象实例保存在oracle数据库中。我对数据库中的每个表都有一个序列。例如,当我在用户或资源上使用保存功能时,它在第一次尝试时创建了一个新资源,但使用的ID是70?该序列显示了正确的下一个数字-42,因为表中的最大id是41。为什么使用id=70来插入新资源?

同样,从下一次尝试开始,所有插入都会失败并出现此错误

org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [insert into GRARESOURCE (decomm
issioned, disabled, criticality, resourceClass, resourceGroupId, resourceName, ownerId, resourceSegmentId, resourceTypeId, riskSco
re, targetIP, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]; constraint [GRA.SYS_C0012183]; nested exception is org.hibernate.e
xception.ConstraintViolationException: Could not execute JDBC batch update

不确定出了什么问题,因为这是在代码重组之后发生的。。。在那里我们将代码移到了新的包中。。

编辑:我找到了原因,请看我的回复。。谢谢各位

序列可能会浪费数字,即表中的每个记录不一定是一个接一个没有间隙的记录。换句话说,即使上一个DB记录的ID为41,您的记录也跳到了70,这并不意味着有问题。

由于表中的最大id为41

序列看不到表的最大值,并获取下一个值。它们存储当前序列号,您将使用下一个值。

您可以使用检查实际号码

select mysequence.currval from dual

您的问题在于GRA.SYS_C0012183约束。看看它检查了什么,如果这是你的主键,也许你可以使用一些更可读的名称,比如MY_TABLE_PK。。。

SYS_C0012183是主键约束吗?它是否不仅仅定义了id列(我认为它是由序列填充的列)?

  • 如何确定序列的下一个值为42?您是否正在为此运行单独的查询
  • 你希望序列能给你无缺口的数字吗?如果是这样,那就是你的期望值有问题。序列返回不同的值,但它们不能保证不会有间隙(事实上,可以保证会有间隙,因为数据库关闭、序列从共享池中清除或事务回滚)
  • 你如何使用序列?桌子上有触发器吗?或者Hibernate配置为使用序列?如果Hibernate被配置为使用序列,那么发布该配置

我意识到了问题的主要原因。我以前使用过SequencePerTableOracleDialect,这是从Burt Beckwith以前的一篇帖子中得到的。当应用程序启动时,方言为每个表创建一个新的序列,类似于域类转换为表。方言还确保每个表id序列仅通过其序列进行管理,并且不会对数据库中的所有插入使用公共序列(这是默认策略)在代码重组过程中,我删除了自定义方言,并使用默认的10g方言。

这就是问题的原因!

我在与序列的下一个值字段相关的表中看到了下一个数字,在这里我知道resource_sequence的下一次val=42,这是正确的,因为资源表中的max(id)是41。

非常感谢各位的真知灼见,在某种程度上帮助我回忆起真正的原因!对于那些需要更多了解风俗方言的人来说,其此处

最新更新