本文介绍了事务标记为仅回滚:我如何找到原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在@Transactional 方法中提交事务时遇到问题:
I am having issues with committing a transaction within my @Transactional method:
methodA() {
methodB()
}
@Transactional
methodB() {
...
em.persist();
...
em.flush();
log("OK");
}
当我从 methodA() 调用 methodB() 时,该方法成功通过,我可以在日志中看到OK".但后来我得到
When I call methodB() from methodA(), the method passes successfuly and I can see "OK" in my logs. But then I get
Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at methodA()...
- 异常中完全缺少 methodB 的上下文 - 我想这可以吗?
- methodB() 中的某些内容将事务标记为仅回滚?我怎样才能找到它?例如,有没有一种方法可以检查诸如
getCurrentTransaction().isRollbackOnly() 之类的东西?
- 这样我就可以逐步执行该方法并找到原因.
- The context of methodB is completely missing in the exception - which is okay I suppose?
- Something within the methodB() marked the transaction as rollback only? How can I find it out? Is there for instance a way to check something like
getCurrentTransaction().isRollbackOnly()?
- like this I could step through the method and find the cause.
推荐答案
我终于明白问题所在了:
I finally understood the problem:
methodA() {
methodB()
}
@Transactional(noRollbackFor = Exception.class)
methodB() {
...
try {
methodC()
} catch (...) {...}
log("OK");
}
@Transactional
methodC() {
throw new ...();
}
结果是即使 methodB
有正确的注释,methodC
却没有.抛出异常时,第二个 @Transactional
将第一个事务标记为仅回滚.
What happens is that even though the methodB
has the right annotation, the methodC
does not. When the exception is thrown, the second @Transactional
marks the first transaction as Rollback only anyway.
这篇关于事务标记为仅回滚:我如何找到原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!