jpa transaction 回滚_spring - JPA:不会回滚嵌套事务方法 - 堆栈内存溢出

本文探讨了在Spring Boot应用中遇到的一个JPA事务处理问题,当在`StuffService`中调用`BarService`的事务方法时,尽管外层方法抛出异常并期望回滚所有更改,但`BarService`的数据库变更仍然被提交。问题涉及了JTA事务管理器、数据源、事务传播属性以及自定义异常。作者提供了详细的服务和存储库代码以寻求解答。
摘要由CSDN通过智能技术生成

UPD 1:经过进一步研究,我认为以下信息可能有用:

我通过WildFly 9.0.2上的JNDI查找获得数据源,然后将其“包装”到HikariDataSource实例中(例如, return new HikariDataSource(jndiDSLookup(dsName)) )。

最终使用的事务管理器是JTATransactionManager 。

我不以任何方式配置事务管理器。

原始问题:

我遇到了JPA / Hibernate和(也许)Spring-Boot的问题,其中即使回退了调用方方法中的更改,也提交了从另一类的事务处理方法调用的一类事务处理方法中引入的数据库更改。他们应该是)。

这是我的交易服务

StuffService :

@Service

@Transactional(rollbackFor = IOException.class)

public class StuffService {

@Inject private BarService barService;

@Inject private StuffRepository stuffRepository;

public Stuff updateStuff(Stuff stuff) {

try {

if (null != barService.doBar(stuff)) {

stuff.setSomething(SOMETHING);

stuff.setSomethingElse(SOMETHING_ELSE);

return stuffRepository.save(stuff);

}

} catch (FirstCustomException e) {

logger.error("Blah", e);

throw new SecondCustomException(e.getMessage());

}

throw new SecondCustomException("Blah 2");

}

// other methods

}

和BarService :

@Service

@Transactional

public class BarService {

@Inject private EntityARepository entityARepository;

@Inject private EntityBRepository entityBRepository;

/*

* updates existing entity A and persists new entity B.

*/

public EntityA doBar(Stuff stuff) throws FirstCustomException {

EntityA a = entityARepository.findOne(/* some criteria */);

a.setSomething(SOMETHING);

EntityB b = new EntityB();

b.setSomething(SOMETHING);

b.setSomethingElse(SOMETHING_ELSE);

entityBRepository.save(b);

return entityARepository.save(a);

}

// other methods

}

EntityARepository和EntityBRepository是非常相似的Spring-Boot存储库,定义如下:

public interface EntityARepository extends JpaRepository{

EntityA findOne(/* some criteria */);

}

FirstCustomException扩展了Throwable

SecondCustomException扩展了RuntimeException

Stuff实体经过版本控制,并且每隔一段时间由StuffService.updateStuff()同时更新。 在那种情况下,对stuff实例之一的更改将按预期回滚,但是barService.doBar()中发生的所有事情最终都会被提交。

这让我为难了不少,因为在这两种方法事务传播应REQUIRED (默认的),而且这两种方法都属于不同的类别,因此@Transactional应同时申请。

但这并没有真正回答我的问题。

谁能告诉我发生了什么事?

谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值