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