Spring Batch tasklet中的嵌套事务不起作用

Posted

技术标签:

【中文标题】Spring Batch tasklet中的嵌套事务不起作用【英文标题】:Nested transaction in SpringBatch tasklet not working 【发布时间】:2022-01-13 09:13:45 【问题描述】:

我正在为我的应用程序使用 SpringBatch。在其中一个批处理作业中,我需要处理多个数据。每个数据都需要多次数据库更新。我需要为一项数据进行一项交易。意思是,如果在处理一个数据时抛出异常,则该数据的数据库更新会回滚,然后继续处理下一个数据。

我已将所有数据库更新放在服务层的一种方法中。在我的 springbatch tasklet 中,我为每个数据调用该方法,如下所示;

for (RequestViewForBatch request : requestList) 
  orderService.processEachRequest(request);

在服务类中方法是这样的;

Transactional(propagation = Propagation.NESTED, timeout = 100, rollbackFor = Exception.class)
  public void processEachRequest(RequestViewForBatch request) 
//update database

执行任务时,它给了我这个错误信息

org.springframework.transaction.NestedTransactionNotSupportedException: Transaction manager does not allow nested transactions by default - specify 'nestedTransactionAllowed' property with value 'true'

但我不知道如何解决这个错误。

任何建议将不胜感激。提前致谢。

【问题讨论】:

【参考方案1】:

tasklet 步骤将在 Spring Batch 驱动的事务中执行。您需要删除 processEachRequest 方法中的 @Transactional

您需要一个容错的面向块的步骤,并配置了跳过策略。在这种情况下,只会跳过有缺陷的项目。请参阅文档的Configuring Skip Logic 部分。你可以找到一个例子here。

【讨论】:

非常感谢。我会尝试面向块的编码! 我开始尝试使用 ItemReader/ItemProcessor/ItemWriter 在面向块的模型中编写它,但在每个循环中我需要处理许多不同表中的许多数据。详细... 1.从表A/获取所有需要处理的记录 2.对于每条记录,更新几个表(表A,表B,表C等),这个过程需要在一个事务中.所以我不知道这是否可以用 ItemReader/Processor/Writer 来完成。

以上是关于Spring Batch tasklet中的嵌套事务不起作用的主要内容,如果未能解决你的问题,请参考以下文章

从 tasklet 步骤将参数添加到作业上下文并在 Spring Batch 的后续步骤中使用

Spring Batch 小任务(Tasklet)步骤

将数据发送到 Spring Batch Item Reader(或 Tasklet)

在 Spring Batch Step、Tasklet 或 Chunks 之间做出决定

Spring Batch - 处理大量数据

spring batch:如何调用我的 RollBack 实现