我有一个作业配置,我在这里加载了一组文件,在加载了一组文件之后我还要并行加载另一组文件,但只有在第一组完全加载后才能加载。第二组具有第一组的参考字段。我认为我可以使用第二个拆分但从未使它工作,在xsd中,你似乎可以定义多个拆分,显然流程对我的要求没有帮助。 那么如何定义两组并行流并按顺序运行?
<job>
<split>
<flow>
<step next="step2"/>
<step id="step2"/>
</flow>
<flow>
<step ...>
</flow>
</split>
<split ../>
Asoub是对的,它很简单,我做了一个简单的配置,它起作用了。因此,我得到的原始问题似乎有一些其他问题,在定义2个拆分时会导致问题。
我使用的简单配置:
<batch:job id="batchJob" restartable="true">
<batch:split id="x" next="y">
<batch:flow>
<batch:step id="a">
<batch:tasklet allow-start-if-complete="true">
<batch:chunk reader="itemReader" writer="itemWriter" commit-interval="2"/>
</batch:tasklet>
</batch:step>
</batch:flow>
<batch:flow>
<batch:step id="b">
<batch:tasklet allow-start-if-complete="true">
<batch:chunk reader="itemReader" writer="itemWriter" commit-interval="2"/>
</batch:tasklet>
</batch:step>
</batch:flow>
</batch:split>
<batch:split id="y" next="e">
<batch:flow>
<batch:step id="c">
<batch:tasklet allow-start-if-complete="true">
<batch:chunk reader="itemReader" writer="itemWriter" commit-interval="2"/>
</batch:tasklet>
</batch:step>
</batch:flow>
<batch:flow>
<batch:step id="d">
<batch:tasklet allow-start-if-complete="true">
<batch:chunk reader="itemReader" writer="itemWriter" commit-interval="2"/>
</batch:tasklet>
</batch:step>
</batch:flow>
</batch:split>
<batch:step id="e">
<batch:tasklet allow-start-if-complete="true">
<batch:chunk reader="itemReader" writer="itemWriter" commit-interval="2"/>
</batch:tasklet>
</batch:step>
</batch:job>
INFO: Job: [FlowJob: [name=batchJob]] launched with the following parameters: [{random=994444}]
Nov 23, 2016 11:33:24 PM org.springframework.batch.core.job.SimpleStepHandler handleStep
INFO: Executing step: [a]
Nov 23, 2016 11:33:24 PM org.springframework.batch.core.job.SimpleStepHandler handleStep
INFO: Executing step: [b]
Nov 23, 2016 11:33:24 PM org.springframework.batch.core.job.SimpleStepHandler handleStep
INFO: Executing step: [c]
Nov 23, 2016 11:33:24 PM org.springframework.batch.core.job.SimpleStepHandler handleStep
INFO: Executing step: [d]
Nov 23, 2016 11:33:24 PM org.springframework.batch.core.job.SimpleStepHandler handleStep
INFO: Executing step: [e]
Nov 23, 2016 11:33:25 PM org.springframework.batch.core.launch.support.SimpleJobLauncher run
INFO: Job: [FlowJob: [name=batchJob]] completed with the following parameters: [{random=994444}] and the following status: [COMPLETED]
答案 0 :(得分:1)
我会使用两个分区步骤。每个分区程序都负责识别其各自集合中的文件,以便处理并发的子步骤
<job>
<step name="loadFirstSet">
<partition partitioner="firstSetPartitioner">
<handler task-executor="asyncTaskExecutor" />
<step name="loadFileFromSetOne>
<tasklet>
<chunk reader="someReader" writer="someWriter" commit-interval="#{jobParameters['commit.interval']}" />
</tasklet>
</step>
</partition>
</step>
<step name="loadSecondSet">
<partition partitioner="secondSetPartitioner">
<handler task-executor="asyncTaskExecutor" />
<step name="loadFileFromSecondSet>
<tasklet>
<chunk reader="someOtherReader" writer="someOtherWriter" commit-interval="#{jobParameters['another.commit.interval']}" />
</tasklet>
</step>
</partition>
</step>
</job>
答案 1 :(得分:1)
正如我在评论中所说,&#34;那么如何定义两组顺序流程,这些并行流程按顺序运行到每个?&#34;本身没有意义,你不能平行和顺序地开始两步。
我仍然认为你想在步骤1中开始加载file2,当step1中的file1完成加载时#34;。这意味着加载文件发生在步骤的中间。我看到了解决这个问题的两种方法。
让我们说这是您的配置:
<job id="job1">
<split id="split1" task-executor="taskExecutor" next="step3">
<flow>
<step id="step1" parent="s1"/>
</flow>
<flow>
<step id="step2" parent="s2"/>
</flow>
</split>
<step id="step3" parent="s4"/> <!-- not important here -->
</job>
<beans:bean id="taskExecutor" class="org.spr...SimpleAsyncTaskExecutor"/>
但是这将立即启动你的平行步骤。您需要阻止步骤2的开始。因此,您需要在step2的Delegate
中使用reader
,它将立即停止加载file2,并等待信号启动读。在step1的代码中,您可以考虑加载完成,然后向step2的委托阅读器发出信号以开始加载file2。
第二个解决方案是:您创建自己的SimpleAsyncTaskExecutor
,它将启动step1并等待来自step1的信号开始step2。它基本上是第一个解决方案,但您在自定义Executor
而不是Delegate
读者中等待信号。 (您可以从SimpleAsyncTaskExecutor
复制源代码以获得想法)
这是有代价的,如果step1永远不会到达它开始加载的信号step2的部分,你的批次将永远挂起。也许加载中的异常可能导致这种情况。至于信号机制,Java有很多方法可以做到这一点(wait()
和notifiy()
,锁,信号量,非标准库可能。)
我不认为在春季批次中会有一些平行步骤触发器之王(但如果有,有人发布它)。
在问你的问题时我已经回答了一点,你需要2次拆分:第一次加载文件A,第二次加载文件B。
<job id="job1">
<split id="splitForSet_A" task-executor="taskExecutor" next="splitForSet_B">
<flow><step id="step1" parent="s1"/></flow>
<flow><step id="step2" parent="s2"/></flow>
<flow><step id="step3" parent="s3"/></flow>
</split>
<split id="splitForSet_B" task-executor="taskExecutor" next="stepWhatever">
<flow><step id="step4" parent="s4"/></flow>
<flow><step id="step5" parent="s5"/></flow>
<flow><step id="step6" parent="s6"/></flow>
</split>
<step id="stepWhatever" parent="sx"/>
</job>
步骤1,2和3将以并行(并加载文件集A)运行,然后,一旦它们全部结束,第二次拆分(splitForSet_B
)将启动并运行步骤4,5和6平行。拆分基本上是包含以并行运行的步骤的步骤。
您只需在每个步骤中指定要使用的文件(因此,对于第二次拆分中的步骤进行第一次拆分时的步骤将有所不同。