Spring 批处理中的分区数据

Partition data mid-job on Spring Batch

我想在 spring 数据中创建一个作业,它应该包含两个步骤:

第 1 步 - 第一步从数据库中读取某些事务并生成将通过 jobContext 属性发送到第 2 步的记录 ID 列表。

第 2 步 - 这应该是一个分区步骤:从属步骤应该根据从第 1 步获得的列表进行分区(每个线程从列表中获得不同的 Id)并执行它们的 read/process/write 操作而不互相干扰。

我的问题是,即使我想根据第 1 步生成的列表对数据进行分区,spring 甚至在第 1 步开始之前就配置了第 2 步(因此调用了分区程序的 partition() 方法) ,所以我不能按时注入分区标准。我尝试在分区程序 bean 上使用 @StepScope,但它仍会尝试在作业开始之前创建分区。

有没有办法在运行时动态创建步骤分区,或者有一种替代方法可以根据步骤 1 提供的列表将步骤划分为线程?


一些背景:

我正在使用 spring 批处理处理批处理作业,它必须处理存储在数据库中的事务。每笔交易都绑定到一个账户(在不同的 table 中),该账户有一个 accountBalance,每当处理交易时也需要更新它。

由于我想使用多线程执行这些操作,我认为避免冲突的一个好方法是根据它们的 accountId 对事务进行分组,并让每个线程只处理属于该特定 accountId 的事务。这样,不会有两个线程同时尝试修改同一个帐户,因为它们的事务将始终属于不同的帐户。

但是,在获得要处理的交易列表并从那里提取列表之前,我不知道需要处理哪些 accountId,因此我需要能够在运行时提供要分区的列表。这就是为什么我认为我可以在上一步中生成该列表,然后进行下一步分区并相应地处理数据。

我采用的方法是否适合此设置?还是我应该寻找其他解决方案?

我找不到像我想要的那样在作业中分割数据的方法,所以我不得不使用这个解决方法:

我没有将作业分成两步,而是将逻辑从第 1 步("setup step")移动到一个服务方法中,该方法 returns 要处理的事务列表,并添加了一个调用到我的分区程序中的 partition() 方法中的那个方法,允许我根据返回的列表创建分区。

这在我的案例中实现了相同的结果,尽管我仍然想知道是否可以在作业中配置分区,因为如果我必须执行更复杂的处理或写入,此解决方案将不起作用在设置步骤中,并希望配置异常处理策略等。如果将设置步骤放在步骤链的中间而不是开头,它可能也不会起作用。