Spring Batch 事务管理 - 多线程步骤

Posted

技术标签:

【中文标题】Spring Batch 事务管理 - 多线程步骤【英文标题】:Spring Batch Transaction Management - Multi Threaded Step 【发布时间】:2021-02-20 04:07:08 【问题描述】:

我在批处理作业中使用多线程步骤来处理来自源数据库的记录并写入目标数据库。 Step 是基于块的,由 JdbcpagingItemReader、Processor 和 JdbcBathItemWriter 组成。我知道,如果在 Step 处理期间发生任何异常,数据库事务将回滚整个块。我想了解这是如何在内部在 Spring 批处理中进行管理的?由于这是多线程步骤,因此无法保证处理器和写入器在块的同一线程中执行。该块可能由不同的线程处理。那么 Spring batch 是如何确保数据库事务在不同线程作用于同一个块的情况下正确回滚的呢?

【问题讨论】:

【参考方案1】:

您的说法不正确:"The chunk may get processed by different Threads."

参考 Spring 批处理文档,关于 Multi-threaded Step,Step 通过在单独的执行线程中读取、处理和写入每个项目块来执行。所以多线程是在Step级别而不是chunck级别启用的,它在自己的线程中执行每个chunk;因此每个线程都将“运行”一个读-进程-写组合。

上述配置的结果是,Step通过在单独的执行线程中读取、处理和写入每个项目块(每个提交间隔)来执行。请注意,这意味着要处理的项目没有固定的顺序,并且与单线程情况相比,块可能包含不连续的项目。除了任务执行器设置的任何限制(例如它是否由线程池支持)之外,tasklet 配置中还有一个节流限制,默认为 4。您可能需要增加此限制以确保线程池是充分利用。

因此,由于每个块都在专用线程上运行,因此事务管理非常简单。

【讨论】:

【参考方案2】:

请使用本地分区,这将使您完全控制执行,并使您清楚地了解每个工作线程读取器+处理器+写入器事务、回滚批量提交和异常处理(您可以添加侦听器)

https://docs.spring.io/spring-batch/docs/current/reference/html/scalability.html#partitioning

我们已经在多个项目中使用了数百万条记录,并且处理性能是对工作线程的终极和完全控制。它确实是一个很棒的框架,大部分批处理问题都是在内部处理的,我们不必担心。让我们知道,您是否需要任何样品。

【讨论】:

是真的..我已经对此进行了测试并且效果很好,但想知道多线程步骤发生了什么..

以上是关于Spring Batch 事务管理 - 多线程步骤的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Spring Batch 多线程步骤在任何处理之前执行所有读取?

Spring Batch多线程卡住没有任何异常输出

Spring Batch 连接池和多线程

Spring Batch 并行读取数据库

Spring Batch 异步处理器配置以获得最佳性能

Spring-batch学习总结—Job,Flow创建及应用,多线程并发,决策器,监听器,参数