【问题标题】:Spring Batch Exponential Retry doesn't kick in even after NullPointerException is thrown即使在抛出 NullPointerException 之后,Spring Batch 指数重试也不会启动
【发布时间】:2014-12-16 20:46:51
【问题描述】:

我有以下配置用于春季批量指数重试,但是当我故意抛出 NullPointerException 时,我看不到重试开始。为什么?

Spring批量指数重试配置:

<bean id="stepParentExponentialRetry" class="org.springframework.batch.core.step.item.FaultTolerantStepFactoryBean" abstract="true">
    <property name="backOffPolicy">
        <bean class="org.springframework.batch.retry.backoff.ExponentialBackOffPolicy">
            <property name="initialInterval" value="10" />
            <property name="maxInterval" value="15" />
            <property name="multiplier" value="5" />
        </bean>
        </property>
</bean>

<!-- Batch Job -->     
<bean id="checkNextRetryTasklet" class="com.XX.XX.XX.RetrySubmitJob" />
    <batch:job id="expoRetryJob" job-repository="jobRepository">
        <batch:step id="expoRetryStep" parent="stepParentExponentialRetry">
            <batch:tasklet ref="checkNextRetryTasklet" transaction-manager="txManager"/>
        </batch:step>
    </batch:job>

重试提交作业:

    public class RetrySubmitJob implements Tasklet{
       @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
   try {        
        logger.debug("--Logger in --Spring batch--- expo --- retry----");
        String orderId = (String)    chunkContext.getStepContext().getJobParameters().get(CommonConstants.ORDER_NUMBER);
        Orders order = null;
        order.getStatus(); // To throw Null pointer exception
        } catch (Exception e) {
            logger.debug(e.fillinStackTrace());
            throw e;
        }

        return RepeatStatus.FINISHED;
        }
    }

在我的单元测试场景中调用此批处理的类:

 JobParameters jobParameters = 
                          new JobParametersBuilder()
                          .addString(CommonConstants.ORDER_NUMBER, orderNmb).toJobParameters();
jobLauncher.run(expoRetryJob, jobParameters);

相关日志:

Hibernate: SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?
Hibernate: SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?
Hibernate: SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?
Hibernate: select BATCH_JOB_SEQ.nextval from dual
Hibernate: INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)
Hibernate: INSERT into BATCH_JOB_PARAMS(JOB_INSTANCE_ID, KEY_NAME, TYPE_CD, STRING_VAL, DATE_VAL, LONG_VAL, DOUBLE_VAL) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: select BATCH_JOB_EXECUTION_SEQ.nextval from dual
Hibernate: INSERT into BATCH_JOB_EXECUTION(JOB_EXECUTION_ID, JOB_INSTANCE_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, VERSION, CREATE_TIME, LAST_UPDATED) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: INSERT INTO BATCH_JOB_EXECUTION_CONTEXT (SHORT_CONTEXT, SERIALIZED_CONTEXT, JOB_EXECUTION_ID) VALUES(?, ?, ?)
Hibernate: SELECT COUNT(*) FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID = ?
Hibernate: UPDATE BATCH_JOB_EXECUTION set START_TIME = ?, END_TIME = ?,  STATUS = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, CREATE_TIME = ?, LAST_UPDATED = ? where JOB_EXECUTION_ID = ? and VERSION = ?
Hibernate: SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION from BATCH_JOB_EXECUTION where JOB_INSTANCE_ID = ? order by JOB_EXECUTION_ID desc
Hibernate: SELECT STEP_EXECUTION_ID, STEP_NAME, START_TIME, END_TIME, STATUS, COMMIT_COUNT, READ_COUNT, FILTER_COUNT, WRITE_COUNT, EXIT_CODE, EXIT_MESSAGE, READ_SKIP_COUNT, WRITE_SKIP_COUNT, PROCESS_SKIP_COUNT, ROLLBACK_COUNT, LAST_UPDATED, VERSION from BATCH_STEP_EXECUTION where JOB_EXECUTION_ID = ? order by STEP_EXECUTION_ID
Hibernate: SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, VERSION from BATCH_JOB_EXECUTION where JOB_INSTANCE_ID = ? order by JOB_EXECUTION_ID desc
Hibernate: SELECT STEP_EXECUTION_ID, STEP_NAME, START_TIME, END_TIME, STATUS, COMMIT_COUNT, READ_COUNT, FILTER_COUNT, WRITE_COUNT, EXIT_CODE, EXIT_MESSAGE, READ_SKIP_COUNT, WRITE_SKIP_COUNT, PROCESS_SKIP_COUNT, ROLLBACK_COUNT, LAST_UPDATED, VERSION from BATCH_STEP_EXECUTION where JOB_EXECUTION_ID = ? order by STEP_EXECUTION_ID
Hibernate: select BATCH_STEP_EXECUTION_SEQ.nextval from dual
Hibernate: INSERT into BATCH_STEP_EXECUTION(STEP_EXECUTION_ID, VERSION, STEP_NAME, JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, COMMIT_COUNT, READ_COUNT, FILTER_COUNT, WRITE_COUNT, EXIT_CODE, EXIT_MESSAGE, READ_SKIP_COUNT, WRITE_SKIP_COUNT, PROCESS_SKIP_COUNT, ROLLBACK_COUNT, LAST_UPDATED) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: INSERT INTO BATCH_STEP_EXECUTION_CONTEXT (SHORT_CONTEXT, SERIALIZED_CONTEXT, STEP_EXECUTION_ID) VALUES(?, ?, ?)
Hibernate: UPDATE BATCH_STEP_EXECUTION set START_TIME = ?, END_TIME = ?, STATUS = ?, COMMIT_COUNT = ?, READ_COUNT = ?, FILTER_COUNT = ?, WRITE_COUNT = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, READ_SKIP_COUNT = ?, PROCESS_SKIP_COUNT = ?, WRITE_SKIP_COUNT = ?, ROLLBACK_COUNT = ?, LAST_UPDATED = ? where STEP_EXECUTION_ID = ? and VERSION = ?
Hibernate: SELECT VERSION FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID=?
Hibernate: UPDATE BATCH_STEP_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE STEP_EXECUTION_ID = ?
--Logger in --Spring batch--- expo --- retry----
java.lang.NullPointerException
    at com.XX.XX.XX.XX.RetrySubmitJob.execute(RetrySubmitJob.java:88)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:386)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:264)
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:76)
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367)
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:214)
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
    at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:250)
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135)
    at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61)
    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:144)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:293)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:114)

【问题讨论】:

  • “X 不起作用”不是问题,而是陈述。
  • 您可以分享任何日志吗?
  • 嗨迈克尔,谢谢你的提问。我在尝试后在第一行使用调试点运行这是调试模式,我没有看到控制返回重试或任何相应的日志
  • @KiranHegde 很好,但我应该说越具体越好。我尝试进行一些编辑。
  • @Superbest 谢谢,只保留 stepParentExponentialRetry 部分

标签: java spring spring-batch spring-retry


【解决方案1】:

Spring Batch 中的容错机制不适用于自定义Tasklets。它仅适用于基于块的处理。使用您自己的自定义 Tasklet 实现时,期望您将实现自己的容错逻辑。

【讨论】:

    猜你喜欢
    • 2016-08-13
    • 1970-01-01
    • 2016-06-21
    • 2020-08-28
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 2021-10-23
    相关资源
    最近更新 更多