首页 > 解决方案 > Oracle 序列在 nextval 之后不增加

问题描述

调用 Oracle 序列 nextval 似乎是不规则的。我们的业务约束(唯一令牌)是生成唯一编号,所以我们使用 oracle 序列。我们使用 hibernate spring boot 应用程序。但是,在这种情况下,我们通过本地查询 (JDBC) 调用 nextval,因此不会发生休眠管理。但是,在生产环境中运行应用程序一段时间后,由于 oracle 序列尝试生成相同的序列号,或者在一段时间后它不会增加序列值,所以唯一令牌得到唯一约束异常。在我们所有的唯一令牌中,序列值的差异就像 1 或 2。但是当序列值不增加时(在 nextval 上),手动序列增加 2494(缓存 1000 ORDER)。我们的序列值是 ORDER 但卡在一些值中,需要增加 2494 以保持我们的唯一性

我们的序列定义是这样的:

CREATE SEQUENCE SEQ_98090 INCREMENT BY 1 CACHE 1000 ORDER NOCYLE NOPARTITION;

为了解决这个问题,我们手动增加序列值,这样我们的唯一业务约束(唯一令牌)就不会得到任何唯一约束异常。

我们的应用程序在多个服务器上运行。

我们从外部调试序列值,我们看到 oracle 序列值没有增加。

CREATE SEQUENCE SEQ_98090 INCREMENT BY 1 CACHE 1000 ORDER NOCYLE NOPARTITION;
String queryString = "SELECT " + dbSequence + ".NEXTVAL FROM DUAL";
Query query = em.createNativeQuery(queryString);
BigDecimal issuedTokenBin = null;
try {
    issuedTokenBin = (BigDecimal) query.getSingleResult();
} catch (Exception ex) {
    log.error("Error :", ex);
}

当我们从 oracle 序列中获取序列时,它应该总是返回递增的值。

从 TID 值 3009053444 到下一个 TID 3009091522,唯一令牌的最后一部分,即预言机序列卡住了。 除非我们手动增加它

来自图片:Oracle 序列卡在第一个选定的行(应用程序违反了唯一约束)。然后我们手动增加它并且应用程序开始运行。唯一令牌的最后 8 位即 79140 和 81634 来自 oracle 序列。

标签: sqloraclesequence

解决方案


序列缓存的总体好处是速度:缓存值越高,Oracle 必须访问数据库并获取序列缓存的次数就越少。缓存的负面影响是,一旦存在序列缓存,如果重新启动数据库,Oracle 就会放弃缓存中的任何值。

因此,如果您不想在序列值中留下空白,则必须通过将序列设置为 NOCACHE 来付出代价。


推荐阅读