繁体   English   中英

Spring StepExecutionListener 中的批量事务

[英]Spring Batch Transactions in StepExecutionListener

我有一个 spring 批处理作业,它从 web 服务读取数据,在处理器中进行一些丰富,然后保存到 DB。 如果有人为同一组参数运行相同的作业两次,我想删除 db 中的旧数据,然后作为该作业的一部分重新写入。

我在 Step 方法之前的 StepExecutionListener 中编写了删除逻辑。

如何使我的步骤具有事务性,以便在作业中出现错误时回滚删除操作?

this.stepBuilderFactory.get("xStep")
.<Item,Item>chunk(1000)
.reader(xReader)
.processor(xProcessor)
.writer(xWriter)
.listener(xStepExecutionListenerForDelete)
.build()

如何使我的步骤具有事务性,以便在作业中出现错误时回滚删除操作?

您可以将删除逻辑编写为项目编写器的一部分,该项目编写器在 Spring Batch 驱动的事务内部调用。 如果事务因任何原因回滚,您的删除操作将被回滚。 请注意,item writer 不仅用于插入数据,还可以用于更新和删除数据( MongoItemWriter#setDelete就是一个例子)。

作业参数

如果已经存在具有相同“识别”作业参数的实例,则作业不会开始。

该作业将关闭,但出现以下异常: org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException

您可以创建一个随机生成的值或日期的作业参数。 在您的侦听器中,您可以验证前一个作业实例的作业参数,不包括您的“唯一”作业参数。

事务监听器

将 @Transactional 注释添加到侦听器以将其包装在事务中。

例子

@Transactional
public class DataErasureListener implements StepExecutionListener {

    @Autowired
    JobExplorer jobExplorer;

    @Override
    public void beforeStep(StepExecution stepExecution) {

        String jobName = stepExecution.getJobExecution().getJobInstance().getJobName();
        Map<String, JobParameter> currentJobParameters = stepExecution.getJobParameters().getParameters();

        int jobInstanceCount = jobExplorer.getJobInstanceCount(jobName);

        if (jobInstanceCount == 1) {
            //No prior run
            return;
        }

        //The list of JobInstances are in descending order of creation. Grab the 2nd one.
        JobInstance priorJobInstance = jobExplorer.getJobInstances(jobName, 0, jobInstanceCount).get(1);
        JobExecution priorJobExecution= jobExplorer.getLastJobExecution(priorJobInstance);
        Map<String, JobParameter> priorJobParameters = priorJobExecution.getJobParameters().getParameters();

        //Compare prior job parameters excluding "unique" job parameters
        currentJobParameters.remove("unique");
        priorJobParameters.remove("unique");

        if (currentJobParameters.equals(priorJobParameters)) {
            //Delete old data
        }
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        return stepExecution.getExitStatus();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM