Аннотация @Retryable в Spring Retry не срабатывает

У меня есть обновление таблицы, которое вызывает взаимоблокировку, и я пытаюсь заставить Spring Retry повторить попытку, когда метод получает какое-то исключение блокировки. Я пытался удалить maxAttempts, значение и отсрочку, но, похоже, он никогда не ловил никаких исключений. Я что-то упускаю? Нужно ли объявлять bean-компонент в файле приложения? Любая помощь приветствуется!

Приложение.Java

@SpringBootApplication
@EnableRetry
public class Application extends SpringBootServletInitializer {

ДетальСервис

@Service
public class DetailService {

    @Retryable(maxAttempts = 5, value = { LockAcquisitionException.class, ConcurrencyFailureException.class }, backoff = @Backoff(delay = 500, multiplier = 2) )
    public void delete(final String detailCode) {
        try {
            this.delete(this.dao.findByDetailCode(detailCode));
        } catch (LockAcquisitionException | ConcurrencyFailureException e) {
            LOG.warn("Locking error! Going to retry", e.getMessage());
            throw e;
        }
    }

    public void delete(Details detail) {
           this.dao.delete(detail);            
    }

    @Retryable(maxAttempts = 5, value = { LockAcquisitionException.class, ConcurrencyFailureException.class }, backoff = @Backoff(delay = 500, multiplier = 2) )
    public void delete(final Integer id) {
        if (id != null) {
            try {
                this.delete(this.dao.findOne(id));
            } catch (LockAcquisitionException | ConcurrencyFailureException e) { 
                 LOG.warn("Locking error! Going to retry", e.getMessage());
                 throw e;
            }
        }
    }

РЕДАКТИРОВАТЬ

Переписал мой DetailService выше, чтобы дать больше деталей и добавить отсутствующие методы.


person TacoTacoBurrito175    schedule 03.08.2016    source источник


Ответы (1)


Если вы вызываете метод delete()DetailService) из того же класса, вы замыкаете прокси-сервер, в который Spring упаковывает bean-компонент.

Класс, который имеет аннотацию, должен быть компонентом, управляемым Spring, а метод delete() должен вызываться из какого-либо другого компонента, управляемого Spring, который имеет доступ к повторяемому компоненту посредством автоматического связывания, внедрения и т. д.

ИЗМЕНИТЬ

Если вам нужно вызвать метод delete() из другого метода в этом классе, вы не можете использовать аннотацию — вместо этого используйте соответствующим образом настроенный RetryTemplate.

person Gary Russell    schedule 03.08.2016
comment
Метод delete () является частью класса dao, который автоматически подключается. dao — это грубый класс репозитория. Извините, что не включил туда весь класс DetailService. Будет ли это по-прежнему коротким замыканием прокси-сервера? - person TacoTacoBurrito175; 04.08.2016
comment
О, извините, неправильно понял. Нет, это не вызывается в одном классе. Он вызывается из контроллера или другой службы - person TacoTacoBurrito175; 04.08.2016
comment
Нет; Я имею в виду метод delete() в этом классе (тот, который аннотирован). Смотрите мое редактирование для другого обходного пути. - person Gary Russell; 04.08.2016
comment
Если вы установите точку останова, вы должны увидеть прокси и RetryTemplate в стеке вызовов между контроллером и этим классом; если нет, то что-то не так с проводкой. - person Gary Russell; 04.08.2016
comment
Вчера вечером я ошибся, что delete() вызывается двумя другими методами в классе. Если я поставлю @Retryable на эти методы, это сработает? Или мне нужно написать свой собственный RetryTemplate? Я стараюсь не писать свое... - person TacoTacoBurrito175; 04.08.2016
comment
Да; пока вызов исходит от внешнего bean-компонента, @Retryable будет работать. Но вам не нужно писать RetryTemplate, просто настройте его и используйте для вызова метода через один из его execute методов. - person Gary Russell; 04.08.2016
comment
Благодарю вас! Я исходил из того, что шаблон Retry Template будет иметь bean-компонент по умолчанию, и мне не нужно было объявлять bean-компонент в классе Application. Как только я это сделал, @Retryable сработало. @Bean public RetryTemplate retryTemplate() { - person TacoTacoBurrito175; 04.08.2016