public class A{
@Async
public void methodA(){
someService.methodB();
}
}
public class someServiceImpl implements someService{
@Transactional(noRollbackFor = Exception.class)
public void methodB(){
try{
//to do
}catch(Exception e){
log.error(e.getMessage());
}
}
}
For example, I used the '@ Transactional' to mark my method hope to commit the transaction when error happened.But the problem still happened like this:
org.springframework.orm.jpa.JpaSystemException: Transaction was marked for rollback only; cannot commit; nested exception is org.hibernate.TransactionException: Transaction was marked for rollback only; cannot commit
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:314)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:540)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:532)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.linkyoyo.wmlink.service.impl.DataShowScheduleComputeServiceImpl$$EnhancerBySpringCGLIB$$b9ee37ac.computeAvgIntegrityRate(<generated>)
at com.linkyoyo.wmlink.schedule.ComputeDataShowService.computeAllFunction(ComputeDataShowService.java:119)
at com.linkyoyo.wmlink.schedule.ComputeDataShowService$$FastClassBySpringCGLIB$$f85885cb.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.TransactionException: Transaction was marked for rollback only; cannot commit
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:228)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:536)
... 16 common frames omitted
How can I deal this problem? Thanks.
javax.transaction RollbackException exception is thrown when the transaction has been marked for rollback only or the transaction has been rolled back instead of committed. This is a local exception thrown by methods in the UserTransaction , Transaction , and TransactionManager interfaces.
However, the application should not attempt to rollback the transaction directly. Instead, it should mark the transaction for rollback only, which sets a flag on the transaction indicating that the transaction cannot be committed.
I'm guessing your service calls some other component that is annotated with @Transactional
, correct? If an exception occurs when calling this other component and is caught in SomeServiceImpl
you will be faced with the exception you describe when the transaction system attempts to commit the transaction in methodB
. Any exception passing an @Transactional
boundary will mark the surrounding transaction as rollback-only, unless you have explicitly told the system otherwise.
If you want the surrounding transaction (i.e. the transaction created for methodB
) to "survive" this exception, you'll need to alter the @Transactional
annotation on the target component (i.e. the component where the Exception is thrown) with noRollbackFor
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With