【问题标题】:Spring batch tasklet in single transaction单个事务中的 Spring 批处理小任务
【发布时间】:2016-12-12 00:59:02
【问题描述】:

我使用 FlatFileItemReader 创建了一个 spring 批处理作业,它从分隔文件中读取数据,然后使用 JdbcBatchItemWriter 写入 DB。我的 setp 配置如下。

<batch:step id="step1">
        <batch:tasklet>
            <batch:chunk reader="fileReader" 
                writer="dbWriter" commit-interval="100">
            </batch:chunk>
        </batch:tasklet>
</batch:step>

上面的配置是为每 100 行打开单独的事务,所以如果在 tasklet(step-1) 完成之前发生故障,那么我无法恢复以前提交的行。有没有办法在单个事务中运行整个 tasklet?。

P.S:我使用 MapJobRepositoryFactoryBean 作为作业存储库,不想在数据库中创建元表以重新启动。

【问题讨论】:

    标签: spring-batch


    【解决方案1】:

    在 Spring 批处理中,一个作业一次总是只有一个事务。

    请注意下图,我们可以看到事务在步骤开始时打开,并在步骤结束时提交。

    Image Source

    事实上,使用 Spring Batch 的主要优点之一是我们作为开发人员不必担心事务管理。即使出现故障,它也会自动回滚整个未提交的事务。

    【讨论】:

    • 当我们在项目中使用spring批处理时,@EnableBatchProcessing注解会为其默认表创建自己的事务。因此,如果您想在我们的应用程序表中执行任何插入、更新或删除操作。我们不得不提到 JpaTransactionManager 而不是默认的 spring 批量事务。
    【解决方案2】:

    (自从我上次使用 Spring Batch 已经有一段时间了,我希望我的理解仍然有效:P)您可以简单地创建一个简单的 tasklet,而不是使用面向夹头的 tasklet。默认情况下,一个简单的 tasklet 将在单个事务中运行。鉴于您已经构建了 reader 和 writer,您可以编写一个 tasklet 来模仿一个面向chuck 的步骤正在执行的操作(只是向您展示这个想法的伪代码):

    public class ReaderWriterTasklet<T> implements Tasklet {
        private ItemReader<T> reader;
        private ItemWriter<T> writer;
        // and corresponding setters
    
        public RepeatStatus execute(StepContribution contribution,
                         ChunkContext chunkContext) {
            List<T> chunk = new LinkedList<T>();
            while (true) {
                T item = reader.read();
                if (item == null) {
                    break;
                } else {
                    chunk.add(item);
                }
            }
            writer.write(chunk);
            return RepeatStatus.FINISHED;
        }
    }
    

    (我相信你应该已经知道如何定义运行 tasklet 的步骤了吧?那我就跳过了)

    另一种肮脏的方式是继续使用块,并将提交间隔设置为Integer.MAX_VALUE。通过这样做,面向块的步骤将不断从读取器获取项目,直到它到达末尾,并以一个大块写入写入器,这一切都发生在 1 个事务中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多