在我的@ transaction方法中提交事务时遇到了问题:
methodA() {
methodB()
}
@Transactional
methodB() {
...
em.persist();
...
em.flush();
log("OK");
}
当我从methodA()调用methodB()时,该方法成功传递,并且我可以在我的日志中看到"OK“。但后来我得到了
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()?
这样的东西--像这样,我可以逐步检查方法并找到原因。发布于 2013-10-11 14:56:36
我终于明白了问题所在:
methodA() {
methodB()
}
@Transactional(noRollbackFor = Exception.class)
methodB() {
...
try {
methodC()
} catch (...) {...}
log("OK");
}
@Transactional
methodC() {
throw new ...();
}
实际情况是,即使methodB
有正确的注释,methodC
也没有。当抛出异常时,第二个@Transactional
无论如何都会将第一个事务标记为仅回滚。
发布于 2013-10-11 14:03:14
当你将你的方法标记为@Transactional
时,在你的方法中发生的任何异常都会将周围的TX标记为只回滚(即使你捕获了它们)。您可以使用@Transactional
注释的其他属性来防止它回滚,如下所示:
@Transactional(rollbackFor=MyException.class, noRollbackFor=MyException2.class)
发布于 2015-09-15 19:58:47
要在不需要重新编码或重新构建的情况下快速获取导致异常的,请在
org.hibernate.ejb.TransactionImpl.setRollbackOnly() // Hibernate < 4.3, or
org.hibernate.jpa.internal.TransactionImpl() // as of Hibernate 4.3
然后在堆栈中向上移动,通常是到某个拦截器。在那里,您可以从一些catch块中读取引起异常的内容。
https://stackoverflow.com/questions/19302196
复制相似问题