Я использую Spring 4.0.5 и Spring Batch 3.0.1
У меня такой простой шаг, и он отлично работает:
<step id="myStep" next="nextStep">
<tasklet transaction-manager="myTxManager" task-executor="myTaskExecutor" throttle-limit="10">
<batch:chunk reader="myItemReader" processor="myPDFItemProcessor" writer="myItemWriter" commit-interval="20">
</batch:chunk>
</tasklet>
</step>
Я пробовал простой пример ограничения пропускной способности (Конфигурация Skip Logic) следующим образом:
<step id="myStep" next="nextStep">
<tasklet transaction-manager="myTxManager" task-executor="myTaskExecutor" throttle-limit="10">
<batch:chunk reader="myItemReader" processor="myPDFItemProcessor" writer="myItemWriter" commit-interval="20" skip-limit="10000000">
<batch:skippable-exception-classes>
<batch:include class="java.lang.Exception" />
</batch:skippable-exception-classes>
</batch:chunk>
</tasklet>
</step>
Когда я пытаюсь добавить эту логику, это предупреждение записывается в файлы журнала:
2015-03-24 16:03:50 [WARN ] [org.springframework.batch.core.step.builder.FaultTolerantStepBuilder.detectStreamInReader(FaultTolerantStepBuilder.java:504)] Asynchronous TaskExecutor detected with ItemStream reader. This is probably an error, and may lead to incorrect restart data being stored.
2015-03-24 16:04:18 [WARN ] [org.springframework.batch.core.step.item.ChunkMonitor.open(ChunkMonitor.java:118)] No ItemReader set (must be concurrent step), so ignoring offset data.
2015-03-24 16:04:18 [WARN ] [org.springframework.batch.core.step.item.ChunkMonitor.getData(ChunkMonitor.java:155)] ItemStream was opened in a different thread. Restart data could be compromised.
Читатель - это JdbcPagingItemReader с saveState, установленным на false.
Процессор представляет собой CompositeItemProcessor.
Писатель - CompositeItemWriter.
Что-то не так с моей конфигурацией? Может быть, мне нужна дополнительная конфигурация для пропущенной логики?
Любая помощь очень ценится. благодаря
Наконец, я мог решить вопрос с подсказкой Сэмми.
Когда у вас есть ItemReader на многопоточном шаге, чтобы сделать этот поток для чтения безопасным, код:
public SynchronizedItemReader<T> implements ItemReader<T> {
private final ItemReader<T> delegate;
public SynchronizedItemReader(ItemReader<T> delegate) {
this.delegate = delegate;
}
public synchronized T read () {
return delegate.read();
}
}
Делегированный элемент ItemReader в этом классе - это текущий элемент ItemReader, который вы хотите сделать потокобезопасным.
Этот примерный класс находится в ссылке, предложенной Samwise.
ВАЖНОЕ ИЗМЕНЕНИЕ: Документы в читателях и писателях элементов, раздел 6.5, объясняют, что делегированный читатель должен быть введен как поток. Я не знаю, почему, но в моей текущей проблеме в этом вопросе читатель делегата не должен вводиться как поток-читатель в куске. Когда я ввел его, он потерпел неудачу.
Надеюсь, это было бы полезно. Благодарю.
JdbcPagingItemReader
сscope=step
иsaveState=false
. Так как он не выглядит потокобезопасным, я протестировал простой пользовательский ItemReader сsynchronized
методом чтения, который делегируется в myItemReader, и он не работает. Итак, что я могу сделать, чтобы сделать потокобезопасный читатель? Или что я могу сделать, чтобы сделать myItemReader поточно- ориентированным ? Большое спасибо.