不支持 SpringBoot 2 事务传播嵌套



我有一个 SpringBoot 2 项目,我正在使用带有休眠的 Spring data jpa 和 MySQL5.7

我在以下用例中遇到问题:我有一个调用另一个服务方法的服务方法。如果第二个服务的方法生成运行时异常,则第一个方法也会标记为回滚,我无法再提交内容。我只想回滚第二种方法,并且仍然在第一种方法中提交一些东西。

我尝试使用传播。嵌套但嵌套事务不允许使用休眠(即使jpaTransactionManager支持它们并且MySQL支持保存点(。

我该如何解决这个问题?我可以以某种方式配置嵌套吗?

请记住,我需要第二种方法来查看第一个提交的更改,因此我无法将第二种方法标记为传播。REQUIRES_NEW

这是澄清我的问题的示例代码:

第一服务.java

@Service
public class FirstServiceImpl implements FirstService
@Autowired
SecondService secondService;
@Autowired
FirstServiceRepository firstServiceRepository;
@Transactional
public void firstServiceMethod() {
    //do something
    ...
    FirstEntity firstEntity = firstServiceRepository.findByXXX();
    firstEntity.setStatus(0);
    firstServiceRepository.saveAndFlush(firstEntity);
    ...
    boolean runtimeExceptionHappened = secondService.secondServiceMethod();
    if (runtimeExceptionHappened) {
        firstEntity.setStatus(1);
        firstServiceRepository.save();
    } else {
        firstEntity.setStatus(2);
        firstServiceRepository.save();
    }
}

第二服务.java

@Service
public class SecondServiceImpl implements SecondService

@Transactional
public boolean secondServiceMethod() {
    boolean runtimeExceptionHappened = false;
    try {
    //do something that saves to db but that may throw a runtime exception
    ...
    } catch (Exception ex) {
        runtimeExceptionHappened = true;
    }
    return runtimeExceptionHappened;
}

所以问题是当 secondServiceMethod(( 引发运行时异常时,它会回滚其操作(没关系(,然后将其返回变量 runtimeExceptionHappen 设置为 false,但随后 firstServiceMethod 被标记为仅回滚,然后

firstEntity.setStatus(1);
firstServiceRepository.save();

未提交。

由于我无法使用嵌套传播,我该如何实现我的目标?

我建议你把它们分成两个单独的事务。

在第一个事务中,以您知道要提交的firstServiceMethod执行当前的所有工作。(例如,通过保存和冲洗(。现在,当您退出此方法时,将提交更改,因此它们将可用于后续调用。

然后,让调用firstServiceMethod调用新的事务方法setFirstEntityStatus()该方法调用secondServiceMethod并根据需要设置实体的状态。

基本上,与其尝试 NEST 事务,不如将它们拆分为两个完全独立的事务,并使用排序来确保第一个的结果可供第二个可用。

最新更新