springjpa中的多事务管理

springjpa中的多事务管理,spring,hibernate,jpa,transactions,spring-transactions,Spring,Hibernate,Jpa,Transactions,Spring Transactions,我正在使用spring4、JPA和hibernate5。我的服务如下: @Transactional(rollbackFor = Exception.class) public methodA() { // do some stuff methodB(); } @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) public methodB() { try {

我正在使用
spring4
JPA
hibernate5
。我的服务如下:

@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:事务仅标记为回滚;无法提交”

你知道我做错了什么吗

我正在使用Spring4、JPA和Hibernate5。我的服务如下:

@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
}
因此,您在同一服务中使用了三种方法

这个亮点很重要,因为SpringAOP是如何工作的

如果在同一类中调用方法,那么其他方法不会被
@Transaction
代理,因此它们仍然使用
methodA
的相同事务。 因此,当事务被
methodB
标记为
rollbackOnly
时,您将看到异常

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

我正在使用Spring4、JPA和Hibernate5。我的服务如下:

@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
}
因此,您在同一服务中使用了三种方法

这个亮点很重要,因为SpringAOP是如何工作的

如果在同一类中调用方法,那么其他方法不会被
@Transaction
代理,因此它们仍然使用
methodA
的相同事务。 因此,当事务被
methodB
标记为
rollbackOnly
时,您将看到异常


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

谢谢您的建议!我将methodB和methodC移动到另一个服务,现在我得到了一个不同的行为:应用程序挂起,并且永远不会返回响应。请注意,methodA和methodC都会更新同一对象,methodA完成后会保存并刷新该对象。知道问题是什么吗?没有异常发生?没有异常存在。根据日志,我看到当对象更新时,应用程序在methodC末尾挂起。经过实验后,当@Transactional行完全从methodB中删除时,问题似乎不会出现。这有意义吗?您是否将B和C移动到另一个
@服务
?一个问题:B和C是否与A访问同一个表?谢谢您的建议!我将methodB和methodC移动到另一个服务,现在我得到了一个不同的行为:应用程序挂起,并且永远不会返回响应。请注意,methodA和methodC都会更新同一对象,methodA完成后会保存并刷新该对象。知道问题是什么吗?没有异常发生?没有异常存在。根据日志,我看到当对象更新时,应用程序在methodC末尾挂起。经过实验后,当@Transactional行完全从methodB中删除时,问题似乎不会出现。这有意义吗?您是否将B和C移动到另一个
@Service
?一个问题:B和C是否与A访问同一个表?