首页 > 解决方案 > 在面向读写块的过程中,Spring Batch 在哪里提交?

问题描述

在我的 java 项目中,我有一个使用 Spring boot的读取 ( FlatFileItemReader) - 写入 ( ) 面向块的过程。JdbcBatchItemWriter使用HikariCp数据源。

查看 Spring 批处理 jdbc 编写器,我们可以找到该部分:

               //some code
                @Override
                public int[] doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
                    for (T item : items) {
                        itemPreparedStatementSetter.setValues(item, ps);
                        ps.addBatch();
                    }
                    return ps.executeBatch();
                }
              //some code

所以基本上在这里,如果我的 Hikari 数据源的setAutocommit参数为true,这意味着在ps.executeBatch()我的数据库将被更新之后。

这里的第一个问题,PreparedStatement.executeBatch() 它是如何处理的?它是提交每个 sql 语句还是在每个 sql 语句的末尾?

setAutocommit参数为false的情况下,ps.executeBatch()不应更新它。

由于 Spring 批处理应该管理事务和提交。我试图找到它在哪里提交,以便更好地理解我遇到的问题。看着ChunkOrientedTasklet,我找不到它在提交的过程中的哪个位置SimpleChunkProcessorTransactionTemplate

所以我的第二个问题是,Spring 批处理在面向块的过程中准确提交到哪里?

编辑:使用 Spring 批处理 3.0.7

编辑:似乎已处理AbstractPlatformTransactionManager.processCommit(DefaultTransactionStatus status)但仍无法理解如何处理。

标签: javaspring-batchcommitspring-jdbcspring-transactions

解决方案


根据Spring Batch 文档,关于“何时提交?”的问题:

5.1 面向块的处理

Spring Batch 在其最常见的实现中使用“面向块”的处理方式。面向块的处理是指一次读取一个数据,并在事务边界内创建将被写出的“块”。从 ItemReader 读入一项,将其交给 ItemProcessor,然后进行聚合。一旦读取的项目数等于提交间隔,就会通过 ItemWriter 写出整个块,然后提交事务。

在此处输入图像描述

下面是上面显示的相同概念的代码表示:

List items = new Arraylist();
for(int i = 0; i < commitInterval; i++){
    Object item = itemReader.read()
    Object processedItem = itemProcessor.process(item);
    items.add(processedItem);
}
itemWriter.write(items);

因此,如果你打算使用 Spring Batch,你不应该设置自动提交,因为这是你应该信任框架为你处理的事情。下面的部分显示了如何配置的示例:

5.1.1 配置步骤

尽管 Step 所需的依赖项列表相对较短,但它是一个极其复杂的类,可能包含许多协作者。为了简化配置,可以使用 Spring Batch 命名空间:

<job id="sampleJob" job-repository="jobRepository">
    <step id="step1">
        <tasklet transaction-manager="transactionManager">
            <chunk reader="itemReader" writer="itemWriter" commit-interval="10"/>
        </tasklet>
    </step>
</job>

上面的配置表示创建面向项目的步骤所需的唯一依赖项:

  • reader - 提供要处理的项目的 ItemReader。

  • writer - 处理 ItemReader 提供的项目的 ItemWriter。

  • transaction-manager - Spring 的 PlatformTransactionManager,将用于在处理期间开始和提交事务。

  • job-repository - JobRepository 将用于在处理期间(就在提交之前)定期存储 StepExecution 和 ExecutionContext。对于内联(在 a 中定义的),它是元素上的一个属性;对于独立步骤,它被定义为 .

  • commit-interval - 在提交事务之前将处理的项目数。


推荐阅读