【问题标题】:Spring Batch - skippable exception in a TaskletStepSpring Batch - TaskletStep 中的可跳过异常
【发布时间】:2014-12-16 16:41:00
【问题描述】:

如果发生某种异常,我正在尝试使作业没有BatchStatus.FAILED

文档谈到在<chunk> 中使用skippable-exception-classes,但我怎样才能在TaskletStep 中做同样的事情?以下代码不起作用:

<batch:step id="sendEmailStep">
    <batch:tasklet>
        <bean class="com.myproject.SendEmail" scope="step" autowire="byType">
            <batch:skippable-exception-classes>
                <batch:include class="org.springframework.mail.MailException" />
            </batch:skippable-exception-classes>
        </bean>
    </batch:tasklet>
</batch:step>

【问题讨论】:

    标签: java spring spring-batch


    【解决方案1】:

    Tasklet 中,异常处理的责任在于Tasklet 的实现。面向块的处理中可用的跳过逻辑是由于ChunkOrientedTasklet 提供的异常处理。如果您想在自己的 Tasklet 实现中跳过异常,您需要在自己的实现中编写代码来执行此操作。

    【讨论】:

    • 嗨,我看了你关于远程分块的教程。我想在那里实现跳过。使用面向块的步骤。我该如何实现它,以便它仍然可以从项目阅读器中读取。有点困惑如何为这个受保护的抽象无效运行(JobParameters jobParameters)实现运行方法抛出异常;`
    • 请对此提出问题。
    • 我已经在link 中提出了一个问题。请帮我解决这个问题
    【解决方案2】:

    我按照 Michael Minella 的建议在 Tasklet 中实现了这个功能:

    abstract class SkippableTasklet implements Tasklet {
    
        //Exceptions that should not cause job status to be BatchStatus.FAILED
        private List<Class<?>> skippableExceptions;
    
        public void setSkippableExceptions(List<Class<?>> skippableExceptions) {
            this.skippableExceptions = skippableExceptions;
        }
    
        private boolean isSkippable(Exception e) {
            if (skippableExceptions == null) {
                return false;
            }
    
            for (Class<?> c : skippableExceptions) {
                if (e.getClass().isAssignableFrom(c)) {
                    return true;
                }
            }
            return true;
        }
    
        protected abstract void run(JobParameters jobParameters) throws Exception;
    
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
                throws Exception {
    
            StepExecution stepExecution = chunkContext.getStepContext().getStepExecution();
            JobExecution jobExecution = stepExecution.getJobExecution();
            JobParameters jobParameters = jobExecution.getJobParameters();
    
            try {
                run(prj);
            } catch (Exception e) {
                if (!isSkippable(e)) {
                    throw e;
                } else {
                    jobExecution.addFailureException(e);
                }
            }
    
            return RepeatStatus.FINISHED;
        }
    }
    

    以 Spring XML 配置为例 SkippableTasklet:

    <batch:tasklet>
        <bean class="com.MySkippableTasklet" scope="step" autowire="byType">
            <property name="skippableExceptions">
                <list>
                    <value>org.springframework.mail.MailException</value>
                </list>
            </property>
        </bean>
    </batch:tasklet>
    

    【讨论】:

    • 您为什么要创建自己的步骤? TaskletStep 处理您的步骤遗漏的大量后台更新和事务语义。我推荐这种方法。
    • 嗨迈克尔,我误读了你的答案。我将其更改为 Tasklet 实现。你觉得这样好吗?
    • 这超出了我的预期。
    猜你喜欢
    • 2014-04-26
    • 2016-03-23
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    相关资源
    最近更新 更多