我有一个 SpringBoot 2 项目,我正在使用带有 MySQL5.7 的休眠数据 jpa我在以下用例中遇到问题:我有一个调用另一个服务方法的服务方法。如果第二个服务的方法产生运行时异常,第一个方法也被标记为回滚,我不能再提交东西了。我只想回滚第二种方法,并且仍然在第一种方法中提交一些东西。我尝试使用propagation.NESTED但是hibernate不允许嵌套事务(即使jpaTransactionManager支持它们并且MySQL支持保存点)。我怎么解决这个问题?我可以以某种方式配置嵌套吗?请记住,我需要第二种方法来查看第一种提交的更改,因此我无法将第二种方法标记为传播。REQUIRES_NEW下面是示例代码来澄清我的问题:FirstServiceImpl.java@Servicepublic class FirstServiceImpl implements FirstService@AutowiredSecondService secondService;@AutowiredFirstServiceRepository firstServiceRepository;@Transactionalpublic 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@Servicepublic class SecondServiceImpl implements SecondService@Transactionalpublic 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() 引发运行时异常时,它回滚其操作(没关系)然后将其返回变量 runtimeExceptionHappened 设置为 false,但是 firstServiceMethod 被标记为仅回滚,然后firstEntity.setStatus(1);firstServiceRepository.save();没有承诺。既然我不能使用 NESTED 传播,我该如何实现我的目标?
1 回答
![?](http://img1.sycdn.imooc.com/533e52b90001456f02000200-100-100.jpg)
慕森卡
TA贡献1806条经验 获得超8个赞
我建议你把它们分成两个单独的事务。
在第一个事务中,完成当前firstServiceMethod
您知道要提交的所有工作。(例如通过 saveAndFlush)。现在,当您退出此方法时,更改已提交,因此它们将可用于后续调用。
然后firstServiceMethod
调用一个新的 Transactional 方法setFirstEntityStatus()
,该方法根据需要调用secondServiceMethod
和设置实体的状态。
基本上,不是尝试嵌套事务,而是将它们拆分为两个完全独立的事务并使用排序来确保第一个的结果对第二个可用。
添加回答
举报
0/150
提交
取消