Служба Aspect Around Transactional вызывает исключение UnexpectedRollbackException

У меня есть аспект методов в транзакционной службе. К сожалению, когда я ловлю ошибки службой, выбрасывается другое исключение. Как я могу предотвратить эту ошибку? * Я искал аналогичный вопрос, но ни одно решение не подходит для моего случая.

@Aspect
@Component
public class ServiceGuard {   
    @Pointcut("execution(* simgenealogy.service.*.*(..))")
    public void persistence() {}

    @Around("persistence()")
    public Object logPersistence(ProceedingJoinPoint joinPoint) { 
        try {
            Object o =  joinPoint.proceed();
            return o;
        } catch (ConstraintViolationException constraintException) {
            // (...)
            return null;
        } catch (Throwable throwable) {
            // (...)
            return null;
        }
    }
}

И журнал ошибок.

2019-07-29 02:10:37.979 ERROR 11300 --- [ion Thread] s.a.g.s.w.ServiceGuard                   :
            Constraint violation: First Name cannot be empty
2019-07-29 02:10:38.023 ERROR 11300 --- [ion Thread] s.a.g.s.w.ServiceGuard                   :
            Constraint violation: Last Name cannot by empty
Exception in thread "JavaFX Application Thread" org.springframework.transaction.UnexpectedRollbackException: Transaction silently rolled back because it has been marked as rollback-only
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:534)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:305)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at 
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
0
0
136
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы ловите исключения, которые, вероятно, возникают по какой-то причине. Затем вы просто возвращаете null как результат ранее выполненного (через proceed()) метода, возможно, в ситуациях, когда ожидается другое, ненулевое возвращаемое значение.

Поскольку вы не предоставляете никакого кода приложения, это спекулятивно, но я предполагаю, что возвращаемое значение null затем присваивается свойству данных, которое должно иметь ненулевое значение (см. нарушения ограничений в вашем журнале). Точнее, вы устанавливаете для имени и фамилии значение null, что приводит к нарушению ограничений, что, в свою очередь, приводит к откату вашей транзакции, поскольку обязательные поля данных не установлены.

Как это исправить? Либо возвращайте ненулевые значения по умолчанию для имени/фамилии (хотя звучит странно), либо допускайте эскалацию исходных исключений вместо того, чтобы поглощать их и вызывать последующие проблемы.

Итог: ваша обработка исключений просто сломана и нуждается в исправлении.

Я возвращаю null, потому что я хотел бы передать это значение в Facade Layer, если возникнет какая-либо ошибка. Это правильное возвращаемое значение. Constraint Error в моем тестовом примере в порядке. Третья ошибка не в порядке. Если я перенесу свой аспект на слой фасада, все будет в порядке.

VANILKA 30.07.2019 19:45

Ваш ответ меня удивляет, но как бы то ни было, в этом случае я запрашиваю MCVE на GitHub, воспроизводя проблему. Аспект без приложения, в который он вплетается, лог с ошибками, которые не являются ошибками, определенно недостаточны для того, чтобы я мог вам помочь.

kriegaex 31.07.2019 02:51
Ответ принят как подходящий

Хорошо, я нашел решение. @Transactional также является аспектом @Arround. Проблема заключалась в упорядочении аспектов. Мой класс Guard на самом деле не был связан с Transaction. Поместите @Order(0) в состояние Guard и @Order(1) в службу @Transactional, решенную проблему.

Другие вопросы по теме