Des*_*ess 17 java spring hibernate transactions rollback
这是我的问题:
我正在Java EE/Spring/Hibernate应用程序上运行批处理.这个批次调用了method1
.这个方法调用一个method2
可以抛出的UserException
(一个类扩展RuntimeException
).这是它的样子:
@Transactional
public class BatchService implements IBatchService {
@Transactional(propagation=Propagation.REQUIRES_NEW)
public User method2(User user) {
// Processing, which can throw a RuntimeException
}
public void method1() {
// ...
try {
this.method2(user);
} catch (UserException e) {
// ...
}
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
在执行继续时捕获异常,但在method1
事务关闭结束时抛出RollbackException.
这是堆栈跟踪:
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:476)
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.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy128.method1(Unknown Source)
at batch.BatchController.method1(BatchController.java:202)
Run Code Online (Sandbox Code Playgroud)
什么时候method2
不抛出这个例外,它运作良好.
我尝试过的:
@Transactional(noRollbackFor={UserException.class}))
上method1
method2
但它没有改变任何东西.
由于异常是在发生回滚的不同事务中抛出的,我不明白为什么它不起作用.我看看这个:Jpa事务javax.persistence.RollbackException:事务标记为rollbackOnly但它并没有真正帮助我.
如果有人能给我一些线索,我会非常感激的.
更新
我通过设置propagation=Propagation.REQUIRES_NEW
调用方法method2
(实际上是发送异常的方法)使其工作.这个方法在一个非常类似于我的类中定义BatchService
.所以我不明白为什么它在这个级别上工作而不是method2
.
method2
为公开,因为@Transactional
如果方法是私有的,则不会考虑注释,如文档中所述:@Transactional注释可以放在接口定义,接口上的方法,类定义或类的公共方法之前.
Exception
而不是RuntimeException
(因为它更合适),但它也没有改变任何东西.即使它正在工作,问题仍然是开放的,因为它有一个奇怪的行为,我想理解为什么它不应该像它应该的那样.
JB *_*zet 36
默认情况下,Spring事务通过使用处理事务和异常的代理包装Spring bean来工作.当你打电话method2()
时method1()
,你完全绕过了这个代理,因此无法启动新的交易,并且你实际上method2()
是通过与通过该呼叫打开的交易相同的交易进行呼叫method1()
.
相反,当你调用另一个注入bean的方法时method1()
,你实际上是在事务代理上调用一个方法.因此,如果此外来方法标记为REQUIRES_NEW,则代理会启动新事务,您可以捕获异常method1()
并恢复外部事务.
这在文档中描述.
归档时间: |
|
查看次数: |
20097 次 |
最近记录: |