Как решить проблему «Транзакция была отмечена только для отката; не может зафиксировать;»? - PullRequest
1 голос
/ 13 марта 2019
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());
        }
    }
}

Например, я использовал '@ Transactional', чтобы пометить мой метод как надежный на фиксацию транзакции, когда произошла ошибка. Но проблема все еще происходила так:

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

Как я могу справитьсяЭта проблема?Спасибо.

1 Ответ

2 голосов
/ 13 марта 2019

Я предполагаю, что ваша служба вызывает какой-то другой компонент, помеченный @Transactional, правильно? Если при вызове этого другого компонента возникает исключение и оно попадает в SomeServiceImpl, вы столкнетесь с описанным вами исключением, когда система транзакций пытается зафиксировать транзакцию в methodB. Любое исключение, пересекающее границу @Transactional, помечает окружающую транзакцию только для отката, если вы явно не указали системе обратное.

Если вы хотите, чтобы окружающая транзакция (т. Е. Транзакция, созданная для methodB) "пережила" это исключение, вам нужно изменить аннотацию @Transactional для компонента target (т.е. компонент, в который выдается исключение) с noRollbackFor.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...