AFAIK 一旦创建 - 以编程方式或通过 DBInit - 序列将持久保存在数据库中。它由一个oracle 序列和BASICSERIESENTRY
表中的一行表示。该序列将在服务器再次重新启动后可用,并且不需要重新创建它。
在服务器上调用 next val 将保留“系列”数字。这将在同步方法中发生 - 例如,从 50 到 100 的数字将被保留并保存在内存中(同步),直到生成器用完间隔。之后,服务器将尝试从数据库中请求另一个系列。这是一个相当古老的优化,旨在减少数据库调用的数量。在每次服务器重新启动时,将再次调用数据库,以便保留一个新系列。
以下是服务器在某些情况下的行为方式,例如,当使用序列号生成器创建订单时。
场景一:单台服务器——创建3个订单,重启服务器,创建3个新订单。
可能的结果:订单号可能是 50、51、52、100、101、102
场景 2:并行服务器创建订单。
可能的及时结果:订单号可能是 100、101、50、102、51、52
请注意,您可能有 1 到 N 个应用服务器,但只有一个管理序列的数据库。
更新
示例用法:
步骤 1)创建序列
@Inject
private NumberSequenceProvider nsp;
public void createSeq()
{
nsp.createSequence(
"SO_1234567890",
"0000000",
"ABC",
1,
1,
Long.MAX_VALUE,
1,
false,
false,
50
);
}
这是数据库中发生的事情:
SELECT * FROM BASICSERIESENTRY WHERE IDENTIFIER = 'SO_1234567890'
IDENTIFIER NUMBERPATTERN SEQUENCENAME OCA
--------------- ---------------- ------------------------------ ----------------------
SO_1234567890 0000000 ABC 0
SELECT *
FROM user_sequences
WHERE sequence_name = 'ABC';
SEQUENCE_NAME MIN_VALUE MAX_VALUE INCREMENT_BY CYCLE_FLAG ORDER_FLAG CACHE_SIZE LAST_NUMBER
------------------------------ ---------------------- ---------------------- ---------------------- ---------- ---------- ---------------------- ----------------------
ABC 1 9223372036854775807 1 N N 50 1
步骤 2)重新启动服务器
步骤 3)试一试
String seq = Stream.
generate(() -> nsp.nextValue("SO_1234567890")).
limit(5).
collect(Collectors.joining(", "));
System.out.println("SEQUENCE: " + seq);
输出:
SEQUENCE: 0000001, 0000002, 0000003, 0000004, 0000005
故障排除:
1)NumberSequenceProvider
在报告任何 Oracle 错误时真的很讨厌。因此,请检查您的错误日志中是否存在以下错误:ORA-04006: START WITH cannot be less than MINVALUE
2) 激活提供程序实现的调试日志并检查相关的调试消息(见注释)。