事务未在春季批处理项目编写器中回滚

Posted

技术标签:

【中文标题】事务未在春季批处理项目编写器中回滚【英文标题】:Trasaction is not rolling back in spring batch item writer 【发布时间】:2020-09-07 14:46:26 【问题描述】:

事务未在春季批次中回滚。我故意抛出异常来测试事务回滚。即使项目写入器抛出异常,数据库事务也正在提交。下面是写入器中保存到数据库中的方法。 compEvent 对象是注入到此类中的 jpa 存储库

private void writeCEs(Map> agentMap) 抛出 FailedCompensationException, Exception 对于(入口>代理:agentMap.entrySet()) agent.getValue().stream().forEach((ce) -> compEvent.save(ce); ); updateRecordFileStatus(agent.getKey()); //postToAccounting(agent.getKey(), agent.getValue()); throw new Exception("正在测试 XA 回滚...");

我尝试使用上述方法标记交易 @Transactional(传播 = Propagation.REQUIRES_NEW,rollbackFor = Exception.class) 它仍然在提交交易。我确定我错过了一些东西。任何帮助将不胜感激。

下面是我的批处理配置

@EnableBatchProcessing @EnableTransactionManagement @Configuration @ComponentScan( "com.pm.*" ) 公共类 TrueBatchConfig 扩展 DefaultBatchConfigurer @自动连线 私有 JobBuilderFactory 工作; @自动连线 私有 StepBuilderFactory 步骤; @自动连线 EventReader 阅读器; @自动连线 私有 EventProcessor 处理器; @自动连线 私人 EventWriter 作家; @豆角,扁豆 受保护的步骤 step1(ThreadPoolTask​​Executor 执行程序) DefaultTransactionAttribute 属性 = new DefaultTransactionAttribute(); 属性.setPropagationBehavior(传播.REQUIRED.value()); 属性.setIsolationLevel(Isolation.DEFAULT.value()); 属性.setTimeout(30); 返回 steps.get("step1")., Map>>chunk(10).reader(reader) .processor(处理器).writer(writer).transactionAttribute(属性).build(); @Bean(name = "firstBatchJob") 公共作业 job(@Qualifier("step1") Step step1) 返回jobs.get("firstBatchJob").start(step1).build();

【问题讨论】:

您使用的是哪个事务管理器?你说compEvent object is jpa repository 所以看起来你正在使用JPA。在这种情况下,我希望您将 Spring Batch 配置为使用 JpaTransactionManager 作为您的步骤。是这样吗? 是的,我正在使用 JpaTransactionManager 【参考方案1】:

根据您的配置,Spring Batch 没有配置为使用您的JpaTransactionManager,您需要覆盖getTransactionManager,参见示例here。在你的情况下,它应该是这样的:

public class TrueBatchConfig extends DefaultBatchConfigurer 

   // .. 

    @Override
    public PlatformTransactionManager getTransactionManager() 
        return new JpaTransactionManager(); // TODO set entity manager factory
    


【讨论】:

我有单独的数据库事务管理器,事务管理器看起来像这样。 @Bean public PlatformTransactionManager trueDSTransactionManager(@Qualifier("trueDSFactory") EntityManagerFactory batchCommEntityManagerFactory) return new JpaTransactionManager(batchCommEntityManagerFactory);实际上,这个问题通过创建一个单独的服务并从 writer 调用这个服务得到了解决。我将我所有的写作都包含在该服务中。现在我看到交易正在回滚。事件 XA 事务也在使用单独的服务。

以上是关于事务未在春季批处理项目编写器中回滚的主要内容,如果未能解决你的问题,请参考以下文章

关于调用方有事务,被调用的SP中也有事务,在嵌套SP中回滚代码的报错处理,好文推荐

事务无法在 codeigniter 中回滚

使用栈处理回滚

Spring - 事务应该在一种方法中提交,但应该在执行数据库事务的其他方法中回滚

PostgreSQL:在 plpgsql 函数中回滚事务?

在itemwriter中,春季批处理未在运行时异常上滚动