将FlatFileItemReader与TaskExecutor一起使用(线程安全)

时间:2017-02-16 10:10:17

标签: java multithreading thread-safety spring-batch flat-file

有很多示例使用TaskExecutorJpaItemWriter。我在下面提供了示例(包括XML和Java Config):

我已经将自己的XML配置用于大型CSV(GB大小),并使用开箱即用的FlatFileItemReader写入数据库。即使没有设置save-state = false或采取任何特殊处理,似乎也没有问题。

现在,JpaItemWriter被记录为,因为它不是线程安全的

我的猜测是,hashCode()通过持久化集合来覆盖“问题”,如果equals()FlatFileItemReader覆盖了实体的业务密钥,则集合没有重复。但是,即使这样,由于非线程安全的读取和处理,也不足以防止重复。

请您澄清一下:在已分配TaskExecutor的Tasklet中使用开箱即用的JPAItemWriter是否正确/正确/安全?无论作家如何。如果没有,我们怎么能在理论上解释使用FlatFileItemReader时缺少错误?

P.S:上面给出的示例链接,使用 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@color/lightblue2" android:layout_width="match_parent" android:id="@+id/rlTickerItem" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:id="@+id/tvCompanySymbol" android:layout_centerVertical="true" android:text="symbol" android:layout_marginStart="4dp" android:layout_marginEnd="4dp" android:textColor="@color/darkGray" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_centerVertical="true" android:text="@string/ask" android:layout_toEndOf="@+id/tvCompanySymbol" android:id="@+id/ask" android:layout_marginStart="4dp" android:layout_marginEnd="1dp" android:textColor="@color/blueButton" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_centerVertical="true" android:layout_toEndOf="@+id/ask" android:layout_marginStart="1dp" android:layout_marginEnd="4dp" android:id="@+id/tvAskAmount" android:textColor="@color/blueButton" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_centerVertical="true" android:text="@string/bid" android:layout_toEndOf="@+id/tvAskAmount" android:id="@+id/bid" android:layout_marginStart="4dp" android:layout_marginEnd="1dp" android:textColor="@color/red" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_centerVertical="true" android:layout_toEndOf="@+id/bid" android:layout_marginStart="1dp" android:layout_marginEnd="4dp" android:paddingEnd="4dp" android:id="@+id/tvBidAmount" android:textColor="@color/red" android:layout_height="wrap_content" /> 和TaskExecutor,但没有提到所有可能的线程安全问题......

1 个答案:

答案 0 :(得分:3)

TL; DR 如果FlatFileItemReader是线程安全的,TaskExecutor使用Writer是安全的。 (假设您不关心重启作业,重试步骤,跳过等等)。

更新:现在有JIRA正式确认saveState需要设置为false(即禁用可重启性),如果有人想使用FlatFileItemReader以线程安全的方式TaskExecutor TaskExecutor

让我们先看看Spring documentation关于使用Writer多线程步骤的内容,从马口听到的内容。

  

Spring Batch提供了ItemWriter和的一些实现   ItemReader。通常他们会在Javadocs中说它们是否是线程安全的   或不,或你必须做些什么来避免并发问题   环境。如果Javadocs中没有信息,您可以查看   实现以查看是否存在任何状态

让我们现在解决您的问题:

  

请您澄清一下:使用它是否正确/正确/安全   已分配的Tasklet中的开箱即用的FlatFileItemReader   一个TaskExecutor?无论作家如何。如果没有,我们怎么解释   从理论上讲,当使用JPAItemWriter时缺少错误?

声明&#34; 作家的Regardess &#34;是不正确的。您使用的FlatFileItemReader必须是线程安全的。 JpaItemWriter Java 文档的线程安全,可以安全地与非线程安全的JpaItemWriter一起使用。解释CoherenceBatchWriter.java如何是线程安全的将使这个答案很长。如果您对特定作者如何处理线程安全感兴趣,我建议您发布另一个问题。 (正如 Spring Batch 文档所述)

  

P.S:我在上面给出的示例链接,使用FlatFileItemReader和TaskExecutor,但没有提到所有可能的线程安全问题..

如果您查看一致性示例,您会看到他们明确修改了图6 中的mapBatch。他们首先创建Map局部变量,以便多个线程拥有自己的NamedCache副本。此外,如果您深入研究 Coherence API,您会发现返回的Writer是线程安全的。

您提供的第二个链接看起来非常冒险,因为RcppArmadillo没有做任何事情来避免竞争条件。这个例子确实是对多线程步骤的错误使用。