Spring JPA中的多事务管理

时间:2018-05-14 14:26:13

标签: spring hibernate jpa transactions spring-transactions

我正在使用Spring 4JPAHibernate 5。我的服务如下:

@Transactional(rollbackFor = Exception.class)
public methodA() {
  // do some stuff
  methodB();
}

@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public methodB() {
  try {
    methodC();
  } catch (Exception e) {
    // only log
  }
}


@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public methodC() {
  // do some stuff
}

我想要达到的目的是:当调用methodA时,在调用methodB之前执行的所有操作都应该保留,与之后发生的事情无关。出于这个原因,我添加了methodB,其唯一目的是创建一个新事务,因此如果methodC的事务回滚,methodA的原始事务也不会回滚。总而言之,我希望第一个事务提交,第二个事务在发生故障时回滚。请注意,methodC无法以任何方式更改。

但是这段代码不起作用,我仍然得到例外:"TransactionException: Transaction was marked for rollback only; cannot commit"

关于我做错的任何想法?

1 个答案:

答案 0 :(得分:4)

  

我使用的是Spring 4,JPA和Hibernate 5.我的服务如下:

因此,您在同一服务

中使用了三种方法

这一亮点很重要,因为Spring AOP的工作原理。

如果您在同一个类中调用方法,则其他方法不会被@Transaction代理,因此他们仍然使用methodA的相同事务。 因此,当rollbackOnly

将交易标记为methodB时,您会看到异常

所以要解决这个问题:你必须将方法methodB移动到另一个服务,以便它可以由Spring代理。