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 sequenceBASICSERIESENTRY 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) 激活提供程序实现的调试日志并检查相关调试消息(参见注释)。