Spring Batch在分块处理方向上回滚整个步骤,而不是当前事务。

huangapple go评论51阅读模式
英文:

Spring Batch Rollback full Step instead of current transaction in chunk orientation

问题

我想从文件中读取项目,并将其插入表中。为此,我正在使用FlatFileItemReaderJdbcBatchItemWriter。我在步骤中使用了分块导向。所以我的步骤会像这样:

private Step createPoliciesStep() {
        return stepBuilderFactory.get("CreatePoliciesStep")
                .<PolicyDTO, PolicyDTO>chunk(2)
                .reader(createPoliciesReaderFunc())
                .writer(createPoliciesWriterFunc())
                .listener(createPoliciesWriteListener)
                .listener(createPoliciesStepListener)
                .build();
}

我设置了提交间隔为2。因此,每2条记录会发生一次提交。例如,在读取第4条记录时抛出了一些异常。这时第3条和第4条记录尚未插入,这是完全可以接受的。我希望回滚前一次事务中提交的第1条和第2条记录(已经提交的记录)。

> 我期望的是在步骤开始之前启动事务。步骤完成后应该进行事务提交。在此期间,任何异常都应该回滚整个步骤。

> 我们有一种简单的方法,在下一步发生任何故障时,我可以删除那些条目。但我觉得这不是一个好的做法。

我尝试通过添加DataSourceTransactionManager的事务管理器和事务属性,但不起作用。在添加后,我的步骤如下所示:

@Bean
PlatformTransactionManager policyTransactionManager(@Qualifier("mysqlDataSource") DataSource dataSource) {
       return new DataSourceTransactionManager(dataSource);
}

private Step createPoliciesStep() {
        log.info("Create Policies Step Initiated ");
        DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
        attribute.setPropagationBehavior(Propagation.REQUIRED.value());
        attribute.setIsolationLevel(Isolation.DEFAULT.value());
        return stepBuilderFactory.get("CreatePoliciesStep")
                .transactionManager(policyTransactionManager)
                .<PolicyDTO, PolicyDTO>chunk(2)
                .reader(createPoliciesReaderFunc())
                .writer(createPoliciesWriterFunc())
                .listener(createPoliciesWriteListener)
                .transactionAttribute(attribute)
                .listener(createPoliciesStepListener)
                .build();
}

有人能否建议一些回滚整个步骤的好方法。提前谢谢!!!

英文:

I want to read items from the file and insert it into the table. For that, I am using FlatFileItemReader and JdbcBatchItemWriter. And I am using Chunk Orientation in the step. So my step will look like this.

private Step createPoliciesStep() {
        return stepBuilderFactory.get(&quot;CreatePoliciesStep&quot;)
                .&lt;PolicyDTO, PolicyDTO&gt;chunk(2)
                .reader(createPoliciesReaderFunc())
                .writer(createPoliciesWriterFunc())
                .listener(createPoliciesWriteListener)
                .listener(createPoliciesStepListener)
                .build();
}

I gave commit-interval is 2. So every 2 records commit will happen. For Example, while reading 4th record some exception is throwing. At that time 3rd and 4th records were not inserted, that is absolutely fine. I want to rollback 1st and 2nd records (which commits on the previous transactions) on my table.

> What I am expecting is before step Begin the transaction. After step should commit the transaction. In between any exception should rollback the entire step.

> We have one simple way, In case of any failure on my next step, I can delete those entries. But I felt it is not a good way to do.

I tried by adding the transaction manager of DataSourceTransactionManager and transaction attributes but not working. After adding my step looks like this

@Bean
PlatformTransactionManager policyTransactionManager(@Qualifier(&quot;mysqlDataSource&quot;)DataSource dataSource) {
       return new DataSourceTransactionManager(dataSource);
}

private Step createPoliciesStep() {
        log.info(&quot;Create Policies Step Initiated &quot;);
        DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
        attribute.setPropagationBehavior(Propagation.REQUIRED.value());
        attribute.setIsolationLevel(Isolation.DEFAULT.value());
        return stepBuilderFactory.get(&quot;CreatePoliciesStep&quot;)
                .transactionManager(policyTransactionManager)
                .&lt;PolicyDTO, PolicyDTO&gt;chunk(2)
                .reader(createPoliciesReaderFunc())
                .writer(createPoliciesWriterFunc())
                .listener(createPoliciesWriteListener)
                .transactionAttribute(attribute)
                .listener(createPoliciesStepListener)
                .build();
}

Can anyone suggest some good method to rollback the full Step. Thanks in advance!!!!

答案1

得分: 1

在Spring Batch中,事务边界是围绕着数据块(chunks)而不是步骤(steps)来定义的。因此,无法为整个步骤配置事务。

针对您的用例,一个常见的模式是添加一个单独的步骤,该步骤根据前一个步骤的退出状态(成功或失败),执行“补偿操作”,即在您的情况下回滚前一个步骤所做的更改。

英文:

Transaction boundaries in Spring Batch are defined around chunks, not steps. So it is not possible to configure a transaction for the entire step.

A common pattern for your use case is to add a separate step that, based on the exit status of the previous step (success or failure), does a "compensating action" which is rolling back the changes of the previous step in your case.

huangapple
  • 本文由 发表于 2020年9月2日 14:06:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63699578.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定