sql - 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 序列中获取序列时,它应该总是返回递增的值。
来自图片:Oracle 序列卡在第一个选定的行(应用程序违反了唯一约束)。然后我们手动增加它并且应用程序开始运行。唯一令牌的最后 8 位即 79140 和 81634 来自 oracle 序列。
解决方案
序列缓存的总体好处是速度:缓存值越高,Oracle 必须访问数据库并获取序列缓存的次数就越少。缓存的负面影响是,一旦存在序列缓存,如果重新启动数据库,Oracle 就会放弃缓存中的任何值。
因此,如果您不想在序列值中留下空白,则必须通过将序列设置为 NOCACHE 来付出代价。
推荐阅读
- quarkus - 保护 eclipse-microprofile 指标和健康端点
- java - 将即时日期从 DB 对象转换为 localDateTime,但在未来的日期会变得很奇怪
- google-sheets - Google 表格:如何在要导入的本地 .tsv 文件的字段中包含换行符
- android - 即使设置了权限,也无法写入 Android 外部存储
- machine-learning - 分类测试集准确率低于验证
- python - 如何用熊猫中的分组平均值替换列的空值?
- java - 来自客户端的 Java (Tomcat) websocket 参数
- c# - 如何使用 C# 代码为 aad 令牌设置自定义声明
- javascript - 在这种情况下我应该使用什么逻辑运算符
- python - Python将CSV中的列修改为多列