gpt4 book ai didi

java - 无法提交 JPA 事务 : Transaction marked as rollbackOnly

转载 作者:IT老高 更新时间:2023-10-28 13:43:46 26 4
gpt4 key购买 nike

我在我正在处理的一个应用程序中使用 Spring 和 Hibernate,但在处理事务时遇到了问题。

我有一个服务类,它从数据库加载一些实体,修改它们的一些值,然后(当一切都有效时)将这些更改提交到数据库。如果新值无效(我只能在设置它们后检查)我不想保留更改。为了防止 Spring/Hibernate 保存更改,我在方法中抛出异常。然而,这会导致以下错误:

Could not commit JPA transaction: Transaction marked as rollbackOnly

这就是服务:

@Service
class MyService {

@Transactional(rollbackFor = MyCustomException.class)
public void doSth() throws MyCustomException {
//load entities from database
//modify some of their values
//check if they are valid
if(invalid) { //if they arent valid, throw an exception
throw new MyCustomException();
}

}
}

这就是我调用它的方式:

class ServiceUser {
@Autowired
private MyService myService;

public void method() {
try {
myService.doSth();
} catch (MyCustomException e) {
// ...
}
}
}

我期望发生的事情:数据库没有变化,用户也看不到异常。

会发生什么:数据库没有更改,但应用程序崩溃:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction;
nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly

它正确地将事务设置为rollbackOnly,但是为什么回滚会因异常而崩溃?

最佳答案

我的猜测是 ServiceUser.method() 本身就是事务性的。不应该。原因如下。

当调用您的 ServiceUser.method() 方法时会发生以下情况:

  1. 事务拦截器拦截方法调用,并启动事务,因为没有事务处于 Activity 状态
  2. 方法被调用
  3. 方法调用 MyService.doSth()
  4. 事务拦截器拦截方法调用,发现事务已经处于 Activity 状态,不做任何事情
  5. doSth() 被执行并抛出异常
  6. 事务拦截器拦截异常,将事务标记为rollbackOnly,并传播异常
  7. ServiceUser.method() 捕获异常并返回
  8. 事务拦截器,因为它已经启动了事务,所以会尝试提交它。但是Hibernate拒绝这样做,因为事务被标记为rollbackOnly,所以Hibernate抛出了异常。事务拦截器通过抛出一个包装 hibernate 异常的异常向调用者发出信号。

现在如果 ServiceUser.method() 不是事务性的,会发生以下情况:

  1. 方法被调用
  2. 方法调用 MyService.doSth()
  3. 事务拦截器拦截方法调用,发现没有事务处于 Activity 状态,因此启动事务
  4. doSth() 被执行并抛出异常
  5. 事务拦截器拦截异常。由于它已经启动了事务,并且由于抛出了异常,所以它回滚事务,并传播异常
  6. ServiceUser.method() 捕获异常并返回

关于java - 无法提交 JPA 事务 : Transaction marked as rollbackOnly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25322658/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com