Spring Batch: повторяющиеся строки после повторного запуска задания

Наше приложение Spring Batch после перезапуска неудачного задания снова обрабатывает те же записи, что приводит к дублированию строк, и мы хотим понять, как этого избежать.

Поллер Spring Integration, запускающий пакетное задание, настроен на запуск каждые пару часов. При повторном запуске параметры задания будут такими же, но если предыдущий запуск завершился неудачно (например, из-за исключения DataTruncation), Spring Batch не будет жаловаться на то, что задание уже выполнено.

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

База данных Spring Batch - это Derby (файловая), она настраивается при запуске приложения, и, похоже, состояние не поддерживается между перезапусками фактического приложения (потому что задание может быть запущено снова с теми же параметрами). Однако при одном запуске приложения состояние сохраняется. Например, если задание завершится успешно, при следующем запуске опроса будет выдано исключение, потому что задание (с этими параметрами) уже завершено.

Наша работа заключается в следующем:

<batch:job id="publisherJob" >
   <batch:step id="step1">
      <batch:tasklet >
    <batch:chunk reader="itemReader" processor="itemProcessor"
              writer="itemWriter" commit-interval="${...}" />
        </batch:tasklet>

        <batch:listeners>
        ...
        </batch:listeners>
</batch:job>

<bean id="itemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
   <property name="dataSource" ref="dataSource" />
   <property name="sql" value="select ${...} from ${...} where ${...}" />
   <property name="rowMapper" ref="rowMapper" />
</bean>

Предложение WHERE включает ORDER BY.

Мы понимали, что Spring Batch сохранит состояние, в котором обработка завершилась неудачно, и продолжит работу с этой точки (если ошибка в исходной таблице была исправлена), тем самым предотвращая дублирование строк. Что нужно настроить, чтобы это произошло?

Спасибо


person user1052610    schedule 07.01.2015    source источник


Ответы (1)


Spring Batch поддерживает состояние, так как запоминает, сколько записей было обработано, а не конкретно какие. Из-за этого вы должны гарантировать, что порядок элементов воспроизводится от запуска к запуску, так что если мы обработаем 100 записей в прогоне 1 и потерпим неудачу, когда мы пропустим первые 100 записей в прогоне 2, это будут правильные 100 записи, которые нужно пропустить. Вы не предоставили конфигурацию для своего JdbcCursorItemReader, но я предполагаю, что вы не используете заказ by в своем SQL. Если вам нужна возможность перезапуска, вам нужен способ гарантировать порядок элементов. Использование order by в вашем SQL - самый простой способ добиться этого (есть и другие, например, использование шаблона индикатора процесса, если это необходимо).

person Michael Minella    schedule 07.01.2015
comment
Спасибо. В нашем JdbcCursorItemReader мы определяем предложение ORDER BY. Вот почему мы всегда при каждом повторном запуске получаем точно такие же строки, вставленные в целевую таблицу. Всегда дублируется один и тот же набор. Поэтому кажется, что Spring Batch всегда начинается с первой строки в исходном наборе результатов. - person user1052610; 07.01.2015
comment
‹Batch: job id = publisherJob› ‹batch: step id = step1› ‹batch: tasklet› ‹batch: chunk reader = itemReader processor = itemProcessor writer = itemWriter commit-interval = $ {...} /› ‹/ batch: тасклет ›‹ batch: listeners ›...‹ / batch: listeners ›‹ / batch: job › - person user1052610; 07.01.2015
comment
Вы уверены, что действительно перезапускаете задание или просто запускаете его снова? - person Michael Minella; 08.01.2015
comment
Как вы их различите? Поллер запускает пакетное задание во второй раз. Это единственный способ перезапустить из Spring Batch Admin? - person user1052610; 08.01.2015
comment
Мне нужно увидеть конфигурацию запуска вашего задания, но есть разница между повторным запуском задания и его перезапуском. Если вы получаете новый JobInstance в репозиторий заданий во второй раз, вы не перезапускаете задание, что означает сброс состояния. В качестве примечания, можете ли вы удалить комментарии выше, в которых вы разместили свою конфигурацию и отметили, что обновили вопрос (чтобы здесь все было в порядке). - person Michael Minella; 08.01.2015
comment
В нашем процессе мы фиксируем идентичность строк по мере их обработки. При инициализации считыватель предварительно загружает набор идентификаторов строк, которые были ранее обработаны. По мере того, как читатель просматривает данные, полученные для обработки, он проверяет набор идентификаторов строк и переходит к следующему, если есть совпадение. - person pojo-guy; 30.07.2016