【问题标题】:Spring Batch: taskExecutor exception when adding skip limitSpring Batch:添加跳过限制时的taskExecutor异常
【发布时间】:2015-03-24 15:21:45
【问题描述】:

我正在使用 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。

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

非常感谢任何帮助。谢谢

【问题讨论】:

  • 我认为这不是因为跳过逻辑,而是因为它是多线程的。尝试 HibernatePagingItemReader,或者如果您不能使用 Hibernate,请尝试编写 ItemReader 的线程安全实现。
  • @SamwiseGamgee,感谢您的建议。 Bean myItemReaderJdbcPagingItemReader 阅读器,具有 scope=stepsaveState=false 。因为它似乎不是线程安全的,所以我测试了一个简单的自定义 ItemReader 和 synchronized 读取方法,它在 myItemReader 中进行委托,但它没有工作。那么,我能做些什么来制作一个线程安全的阅读器呢?或者我该怎么做才能使 myItemReader 成为线程安全的?非常感谢。
  • 你在使用休眠吗?
  • forum.spring.io/forum/spring-projects/batch/… 这个链接解释了如何实现线程安全。
  • 不,我没有使用 Hibernate

标签: java spring spring-batch


【解决方案1】:

最后,我可以通过 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 节解释了委托阅读器必须作为流注入。我不知道为什么,但在我当前的这个问题中,委托阅读器不能作为流阅读器注入到块中。当我注入它时,它失败了。

希望对您有所帮助。 谢谢。

【讨论】:

  • 这对我不起作用。投诉org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read.
  • @dbreaux,试试在块配置中“作为流注入”。
猜你喜欢
  • 2014-04-26
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多