Весенняя повторная попытка с транзакционной аннотацией

#spring-boot #spring-data-jpa #spring-jdbc #jdbctemplate #spring-retry

Вопрос:

Является ли приведенный ниже код правильным способом использовать повторную попытку Spring с транзакцией? Или мне нужно позаботиться о чем-нибудь дополнительном ? Я использую последнюю версию Spring Boot, Повторяется ли повторная попытка после закрытия неудачной транзакции ?

 @Repository
public class MyRepository {


    @Retryable( value = CustomRetryAbleException.class, maxAttempts = 2, backoff = @Backoff(delay = 30000))
    @Transactional
    Employee updateAndGetEmployee(String date) throw CustomRetryAbleException;
    
    {
         try{
         
        jdbcTemplate.exceute( ....) ; //Call Stored Proc
        }
        
        catch(CustomRetryAbleException c )
        {
          throw  CustomRetryAbleException (" Retry this Exception " );
        }
    }
    
 

Ответ №1:

«Это тот самый путь».

Не забудьте поместить аннотацию @EnableRetry либо в свой класс конфигурации (с аннотацией @Configuration), либо в класс приложения (с аннотацией @SpringBootApplication).

Прочитайте это для получения дополнительной информации.

Вы можете просто зарегистрировать что-то и намеренно заставить его не видеть, будет ли оно снова зарегистрировано после задержки.

Комментарии:

1. Похоже, что Spring связывает цепочку рекомендаций сначала с перехватчиком повторных попыток, а затем с перехватчиком транзакций, поэтому для каждой попытки создается новая транзакция (что хорошо). Если вы хотите убедиться в этом, вы можете использовать 2 компонента с аннотациями «внешний» @Retryable и «внутренний» @Transactional .

2. @GaryRussell итак, пример кода, которым я поделился, верен ?

3. Пока вы выполнили то, что сказал @H3AR7B3A7, но, как я уже сказал, если у вас есть повторяемый боб, вызывающий транзакционный боб, вы можете быть уверены, что перехваты всегда будут в правильном порядке. Я бы сделал это таким образом, чтобы несколько разделить проблемы.

4. @GaryRussell . Кажется, я тебя раскусил . Итак, вы хотите, скажем m1() , позвонить updateAndGetEmployee m1 @Retryable updateAndGetEmployee и прокомментировать с помощью и аннотировать с @Transactional помощью . Это правильно?

5. Правильно, но они должны быть в отдельных компонентах, а не в 2 методах одного класса, таким образом, компонент с m1() получает перехватчик повторных попыток, а репозиторий получает перехватчик транзакций. Как я уже сказал, в этом нет необходимости (по крайней мере, в моем тесте), но я не знаю, является ли порядок добавления перехватчиков детерминированным, или мне просто «повезло», поэтому я предпочитаю быть более явным, чтобы точно знать порядок применения перехватчиков.