Spring 批处理决定器未执行
Spring Batch decider not executing
我有一个带有决策程序的简单批处理作业。决策器实现仅将错误添加到列表,然后 returns 原始 FlowExecutionStatus。解析器失败并退出,而不是失败并执行决策步骤。为什么? (我知道 ErrorHandler 没有被调用,因为输出从不包含记录器输出“in decider asdf”。此外,调试 xml 的最佳方法是什么?任何帮助都会不胜感激。
<batch:job id="testDecider">
<batch:step id="testme" next="testerDecider">
<batch:tasklet>
<batch:chunk reader="csvSLHistoryFileReader"
processor="stationSendStatsCalculator" skip-limit="5" commit-interval="10"
writer="noOpWriter">
<batch:skippable-exception-classes>
<batch:include class="org.springframework.batch.item.file.FlatFileParseException"/>
</batch:skippable-exception-classes>
</batch:chunk>
</batch:tasklet>
</batch:step>
<!-- this commit interval can be 1 because all the input from previous step will be completed and this step will
iterate through the created to-from list -->
<batch:step id="doTallies">
<batch:tasklet>
<batch:chunk reader="stationSendCountsListReader"
processor="passThrough" commit-interval="100000"
writer="stationSubtotalsFileWriter">
</batch:chunk>
</batch:tasklet>
</batch:step>
<batch:step id="tryTesterInput">
<batch:tasklet>
<batch:chunk reader="csvSSHistoryFileReader"
processor="stationSendStatsCalculator" skip-limit="5" commit-interval="10"
writer="noOpWriter">
<batch:skippable-exception-classes>
<batch:include class="org.springframework.batch.item.file.FlatFileParseException"/>
</batch:skippable-exception-classes>
</batch:chunk>
</batch:tasklet>
</batch:step>
<batch:decision id="testerDecider" decider="errorHandler">
<batch:next on="FAILED" to="tryTesterInput"/>
<batch:next on="*" to="doTallies"/>
</batch:decision>
</batch:job>
错误处理程序:
public class ErrorHandler implements JobExecutionDecider {
@Resource List<String> errorsList;
private final Log logger = LogFactory.getLog(getClass());
private String badInput = "none";
private int newErrors = 0;
/* (non-Javadoc)
* @see org.springframework.batch.core.job.flow.JobExecutionDecider#decide(org.springframework.batch.core.JobExecution, org.springframework.batch.core.StepExecution)
*/
@Override
public FlowExecutionStatus decide(JobExecution jobExecution,
StepExecution stepExecution) {
logger.info("in decider asdf");
if (stepExecution.getExitStatus().getExitCode().equals("ERRORS")){
if (errorsList.size() > 0){
newErrors = errorsList.size();
logger.info("Errors encountered in previous step: "+ errorsList.size());
return new FlowExecutionStatus ("FAILED");
}
}
return new FlowExecutionStatus(jobExecution.getStatus().toString());
}
}
异常:
12:47:37,180 [main] INFO ProcessStatisticsTasklet - constructor...
12:47:37,529 [main] INFO RequestsListReader - constructing requestsListReader
12:47:37,662 [main] INFO SimpleJobLauncher - Job: [FlowJob: [name=testDecider]] launched with the following parameters: [{csvHistoryFileName=input/ssXactHistory.csv, csvStationsProfileName=input/bostonStationsProfile.csv, RequestGenerationFileName=input/bostonRequestGeneration.xlsx}]
12:47:37,680 [main] INFO SimpleStepHandler - Executing step: [testme]
12:47:37,759 [main] ERROR AbstractStep - Encountered an error executing step testme in job testDecider
org.springframework.batch.core.step.skip.SkipLimitExceededException: Skip limit of '5' exceeded
at org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy.shouldSkip(LimitCheckingItemSkipPolicy.java:133)
at org.springframework.batch.core.step.skip.ExceptionClassifierSkipPolicy.shouldSkip(ExceptionClassifierSkipPolicy.java:70)
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.shouldSkip(FaultTolerantChunkProvider.java:134)
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:91)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doInIteration(SimpleChunkProvider.java:114)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:108)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:395)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
at org.springframework.batch.core.step.tasklet.TaskletStep.doInChunkContext(TaskletStep.java:267)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:253)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:141)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:151)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:130)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:134)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:48)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:127)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:351)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:577)
Caused by: org.springframework.batch.item.file.FlatFileParseException: Parsing error at line: 6 in resource=[URL [file:input/ssXactHistory.csv]], input=[12/07/14 19:58:54,12/07/14 19:58:54,12/07/14 20:00:02,0,0,12,54,67,19,0,1,0,1,,,,[157] 20:00:02 Empty Zone:16 Station:165 YK L/D ===> Interzone:110 ===> Zone:5 Station:53 NS 5 W ,Station:165 YK L/D,Station:53 NS 5 W,None,None,,,Zone:16 ,Zone:5 ,]
异常很明显,因为已达到跳过限制 5,这将导致步骤失败。当对下一个状态使用 <step ... next="someStep">
表示法时,下一个状态仅在步骤成功完成时执行(在您的情况下没有)。因此,您的决定不会执行。相反,您需要使用定义去哪里的长手版本:
<step>
...
<next on="FAILED" to="testerDecider"/>
</step>
我有一个带有决策程序的简单批处理作业。决策器实现仅将错误添加到列表,然后 returns 原始 FlowExecutionStatus。解析器失败并退出,而不是失败并执行决策步骤。为什么? (我知道 ErrorHandler 没有被调用,因为输出从不包含记录器输出“in decider asdf”。此外,调试 xml 的最佳方法是什么?任何帮助都会不胜感激。
<batch:job id="testDecider">
<batch:step id="testme" next="testerDecider">
<batch:tasklet>
<batch:chunk reader="csvSLHistoryFileReader"
processor="stationSendStatsCalculator" skip-limit="5" commit-interval="10"
writer="noOpWriter">
<batch:skippable-exception-classes>
<batch:include class="org.springframework.batch.item.file.FlatFileParseException"/>
</batch:skippable-exception-classes>
</batch:chunk>
</batch:tasklet>
</batch:step>
<!-- this commit interval can be 1 because all the input from previous step will be completed and this step will
iterate through the created to-from list -->
<batch:step id="doTallies">
<batch:tasklet>
<batch:chunk reader="stationSendCountsListReader"
processor="passThrough" commit-interval="100000"
writer="stationSubtotalsFileWriter">
</batch:chunk>
</batch:tasklet>
</batch:step>
<batch:step id="tryTesterInput">
<batch:tasklet>
<batch:chunk reader="csvSSHistoryFileReader"
processor="stationSendStatsCalculator" skip-limit="5" commit-interval="10"
writer="noOpWriter">
<batch:skippable-exception-classes>
<batch:include class="org.springframework.batch.item.file.FlatFileParseException"/>
</batch:skippable-exception-classes>
</batch:chunk>
</batch:tasklet>
</batch:step>
<batch:decision id="testerDecider" decider="errorHandler">
<batch:next on="FAILED" to="tryTesterInput"/>
<batch:next on="*" to="doTallies"/>
</batch:decision>
</batch:job>
错误处理程序:
public class ErrorHandler implements JobExecutionDecider {
@Resource List<String> errorsList;
private final Log logger = LogFactory.getLog(getClass());
private String badInput = "none";
private int newErrors = 0;
/* (non-Javadoc)
* @see org.springframework.batch.core.job.flow.JobExecutionDecider#decide(org.springframework.batch.core.JobExecution, org.springframework.batch.core.StepExecution)
*/
@Override
public FlowExecutionStatus decide(JobExecution jobExecution,
StepExecution stepExecution) {
logger.info("in decider asdf");
if (stepExecution.getExitStatus().getExitCode().equals("ERRORS")){
if (errorsList.size() > 0){
newErrors = errorsList.size();
logger.info("Errors encountered in previous step: "+ errorsList.size());
return new FlowExecutionStatus ("FAILED");
}
}
return new FlowExecutionStatus(jobExecution.getStatus().toString());
}
}
异常:
12:47:37,180 [main] INFO ProcessStatisticsTasklet - constructor...
12:47:37,529 [main] INFO RequestsListReader - constructing requestsListReader
12:47:37,662 [main] INFO SimpleJobLauncher - Job: [FlowJob: [name=testDecider]] launched with the following parameters: [{csvHistoryFileName=input/ssXactHistory.csv, csvStationsProfileName=input/bostonStationsProfile.csv, RequestGenerationFileName=input/bostonRequestGeneration.xlsx}]
12:47:37,680 [main] INFO SimpleStepHandler - Executing step: [testme]
12:47:37,759 [main] ERROR AbstractStep - Encountered an error executing step testme in job testDecider
org.springframework.batch.core.step.skip.SkipLimitExceededException: Skip limit of '5' exceeded
at org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy.shouldSkip(LimitCheckingItemSkipPolicy.java:133)
at org.springframework.batch.core.step.skip.ExceptionClassifierSkipPolicy.shouldSkip(ExceptionClassifierSkipPolicy.java:70)
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.shouldSkip(FaultTolerantChunkProvider.java:134)
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:91)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doInIteration(SimpleChunkProvider.java:114)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:108)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:395)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
at org.springframework.batch.core.step.tasklet.TaskletStep.doInChunkContext(TaskletStep.java:267)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:253)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:141)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:151)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:130)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:134)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:48)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:127)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:351)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:577)
Caused by: org.springframework.batch.item.file.FlatFileParseException: Parsing error at line: 6 in resource=[URL [file:input/ssXactHistory.csv]], input=[12/07/14 19:58:54,12/07/14 19:58:54,12/07/14 20:00:02,0,0,12,54,67,19,0,1,0,1,,,,[157] 20:00:02 Empty Zone:16 Station:165 YK L/D ===> Interzone:110 ===> Zone:5 Station:53 NS 5 W ,Station:165 YK L/D,Station:53 NS 5 W,None,None,,,Zone:16 ,Zone:5 ,]
异常很明显,因为已达到跳过限制 5,这将导致步骤失败。当对下一个状态使用 <step ... next="someStep">
表示法时,下一个状态仅在步骤成功完成时执行(在您的情况下没有)。因此,您的决定不会执行。相反,您需要使用定义去哪里的长手版本:
<step>
...
<next on="FAILED" to="testerDecider"/>
</step>