Intershop7: Как правильно использовать NumberSequenceProvider

Я работаю над последней и самой лучшей версией Intershop 7.8.0.3 и пытаюсь реализовать новую функциональность, которая генерирует уникальный, читаемый человеком SKU. Моей первой идеей было использование NumberSeriesProvider для реализации функциональности. Однако, к сожалению, этот класс помечен как устаревший и явно заменен на NumberSequenceProvider. К сожалению, для этой функции существует огромный пробел в документации.

Все идет нормально. NumberSequenceProvider также предоставляет метод nextValue (sequenceid) для предоставления следующей записи последовательности. Моя проблема в том, как определить sequenceid. Я видел, что есть метод createSequence (...), который можно использовать для этого. Этот метод добавляет последовательность в базу данных, а также сохраняет sequenceid в локальном кэше sequenceNumberGenerators. Без вызова метода createSequence (...) последовательность, насколько я вижу, никогда не будет доступна методу nextValue (sequenceId), и поэтому вызов этого метода приведет к ошибке.

Я не понимаю, как это должно работать в производственном сценарии с несколькими серверами приложений. На самом деле мне нужно вызывать метод createSequence (...) на каждом запуске сервера, чтобы сделать последовательность доступной в локальном кэше sequenceNumberGenerators. Этот подход всегда будет пытаться создать последовательность в базе данных, что приведет к возникновению исключительной ситуации, если последовательность уже была создана при предыдущем запуске или на параллельном сервере приложений.

Это как это должно работать?

Спасибо и наилучшими пожеланиями

1 ответ

Решение

AFAIK после создания - программно или через DBInit - последовательность сохраняется в базе данных. Он представлен последовательностью оракула и строкой в BASICSERIESENTRY Таблица. Последовательность будет доступна после перезапуска сервера, и не будет необходимости ее воссоздавать.

При вызове следующего значения на сервере резервируется "серия" номеров. Это будет происходить в рамках синхронизированного метода - например, числа от 50 до 100 будут зарезервированы и сохранены в памяти (синхронизированы), пока интервал не будет исчерпан генератором. После этого сервер попытается запросить другую серию из базы данных. Это оптимизация с древних времен, целью которой является уменьшение количества обращений к базе данных. При каждом перезапуске сервера база данных будет вызываться снова, поэтому новая серия резервируется.

Вот как будут вести себя сервер (ы) в некоторых случаях, когда, например, создаются заказы с помощью генератора порядковых номеров.

Сценарий 1. Один сервер - создано 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) Активируйте журнал отладки для реализации провайдера и проверьте наличие связанных сообщений отладки (см. Комментарии).

Другие вопросы по тегам