Spring Batch:添加跳过限制时的taskExecutor异常

时间:2015-03-24 15:21:45

标签: java spring spring-batch

我使用的是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>

我尝试了一个简单的跳过限制示例(Configuring 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。

我的配置有什么问题吗?也许我需要任何其他配置才能使跳过逻辑工作?

非常感谢任何帮助。感谢

1 个答案:

答案 0 :(得分:2)

最后,我可以用Samwise的提示来解决我的问题。

如果在多线程步骤中有一个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建议的链接中。

重要编辑:Item Readers and Writers第6.5节中的文档解释了必须将委派的阅读器作为流注入。我不知道为什么,但在我这个问题的当前问题中,代理阅读器不能作为流阅读器注入块中。当我注射它时,它失败了。

希望它会有所帮助。 感谢。