Intershop7:如何正确使用NumberSequenceProvider
Intershop7: How to use NumberSequenceProvider correctly
我正在开发最新最好的 Intershop 7.8.0.3,并且正在尝试实现一个新功能,该功能可以生成一个独特的、人类可读的 SKU。我的第一个想法是使用 NumberSeriesProvider 来实现功能。然而,不幸的是,这个 class 被标记为已弃用,并且显然已被 NumberSequenceProvider 取代。不幸的是,此功能存在巨大的文档空白。
到目前为止一切顺利。 NumberSequenceProvider 还提供了一个方法 nextValue(sequenceid) 来提供下一个序列条目。我的问题是如何定义 sequenceid。我已经看到有一个方法 createSequence(...) 可以用来这样做。此方法将序列添加到数据库中,并将 sequenceid 存储在本地 sequenceNumberGenerators 缓存中。在不调用 createSequence(...) 方法的情况下,序列 - 据我所知 - 永远无法用于 nextValue(sequenceId) 方法,因此调用此方法将导致错误。
我不明白这在具有多个应用程序服务器的生产场景中应该如何工作。实际上,我需要在每个服务器启动时调用 createSequence(...) 方法,以使序列在本地 sequenceNumberGenerators 缓存中可用。这种方法总是会尝试在数据库中创建序列,如果序列已经在上一次启动时创建或由并行应用程序服务器创建,则会导致捕获异常。
这是它应该的工作方式吗?
谢谢你和最好的问候
AFAIK 一旦创建 - 以编程方式或通过 DBIinit - 序列将保存在数据库中。它由 oracle sequence 和 BASICSERIESENTRY
table 中的一行表示。该序列将在服务器再次重新启动后可用,并且不需要重新创建它。
在服务器上调用 next val 将保留 "series" 个号码。这将在同步方法中发生——例如从 50 到 100 的数字将被保留并保存在内存中(同步),直到生成器耗尽间隔。之后服务器将尝试从数据库中请求另一个系列。这是一个相当古老的优化,旨在减少数据库调用的数量。每次重新启动服务器时,都会再次调用数据库,因此会保留一个新系列。
这是服务器在某些情况下的行为方式,例如使用序列号生成器创建订单时。
场景一:单台服务器-创建3个订单,重启服务器,创建3个新订单。
可能的结果:订单号可能是50,51,52,100,101,102
场景 2: 并行服务器创建订单。
可能的时间结果:订单号可能是 100、101、50、102、51、52
请注意,您可能有 1 到 N 个应用服务器,但只有一个 DB 来管理序列。
更新
示例用法:
步骤 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) 激活提供程序实现的调试日志并检查相关调试消息(参见注释)。
我正在开发最新最好的 Intershop 7.8.0.3,并且正在尝试实现一个新功能,该功能可以生成一个独特的、人类可读的 SKU。我的第一个想法是使用 NumberSeriesProvider 来实现功能。然而,不幸的是,这个 class 被标记为已弃用,并且显然已被 NumberSequenceProvider 取代。不幸的是,此功能存在巨大的文档空白。
到目前为止一切顺利。 NumberSequenceProvider 还提供了一个方法 nextValue(sequenceid) 来提供下一个序列条目。我的问题是如何定义 sequenceid。我已经看到有一个方法 createSequence(...) 可以用来这样做。此方法将序列添加到数据库中,并将 sequenceid 存储在本地 sequenceNumberGenerators 缓存中。在不调用 createSequence(...) 方法的情况下,序列 - 据我所知 - 永远无法用于 nextValue(sequenceId) 方法,因此调用此方法将导致错误。
我不明白这在具有多个应用程序服务器的生产场景中应该如何工作。实际上,我需要在每个服务器启动时调用 createSequence(...) 方法,以使序列在本地 sequenceNumberGenerators 缓存中可用。这种方法总是会尝试在数据库中创建序列,如果序列已经在上一次启动时创建或由并行应用程序服务器创建,则会导致捕获异常。
这是它应该的工作方式吗?
谢谢你和最好的问候
AFAIK 一旦创建 - 以编程方式或通过 DBIinit - 序列将保存在数据库中。它由 oracle sequence 和 BASICSERIESENTRY
table 中的一行表示。该序列将在服务器再次重新启动后可用,并且不需要重新创建它。
在服务器上调用 next val 将保留 "series" 个号码。这将在同步方法中发生——例如从 50 到 100 的数字将被保留并保存在内存中(同步),直到生成器耗尽间隔。之后服务器将尝试从数据库中请求另一个系列。这是一个相当古老的优化,旨在减少数据库调用的数量。每次重新启动服务器时,都会再次调用数据库,因此会保留一个新系列。
这是服务器在某些情况下的行为方式,例如使用序列号生成器创建订单时。
场景一:单台服务器-创建3个订单,重启服务器,创建3个新订单。
可能的结果:订单号可能是50,51,52,100,101,102
场景 2: 并行服务器创建订单。
可能的时间结果:订单号可能是 100、101、50、102、51、52
请注意,您可能有 1 到 N 个应用服务器,但只有一个 DB 来管理序列。
更新 示例用法:
步骤 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) 激活提供程序实现的调试日志并检查相关调试消息(参见注释)。