0

我正在开发最新最好的 Intershop 7.8.0.3,并试图实现一个新功能,它可以生成一个独特的、人类可读的 SKU。我的第一个想法是使用 NumberSeriesProvider 来实现该功能。但是,不幸的是,此类被标记为已弃用,并且显然已替换为 NumberSequenceProvider。不幸的是,此功能存在巨大的文档空白。

到目前为止,一切都很好。NumberSequenceProvider 还提供了一个方法 nextValue(sequenceid) 来提供下一个序列条目。我的问题是如何定义sequenceid。我已经看到有一种方法 createSequence(...) 可以用来这样做。此方法将序列添加到数据库中,并将 sequenceid 存储在本地 sequenceNumberGenerators 缓存中。如果不调用 createSequence(...) 方法,则序列 - 据我所知 - nextValue(sequenceId) 方法永远不可用,因此调用此方法将导致错误。

我不明白这应该如何在具有多个应用程序服务器的生产场景中工作。实际上,我需要在每个服务器启动时调用 createSequence(...) 方法,以使序列在本地 sequenceNumberGenerators 缓存中可用。这种方法总是会尝试在数据库中创建序列,如果序列已在先前启动时创建或由并行应用程序服务器创建,则会导致捕获的异常。

这是它应该如何工作的吗?

感谢你并致以真诚的问候

4

1 回答 1

1

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

于 2017-03-28T13:57:48.040 回答