Я знаю, что вы можете комбинировать @Transactional
и @Retryable
, как это
@Retryable(value = ObjectOptimisticLockingFailureException.class)
@Transactional
public void doStuff() {}
Причина, по которой я хотел бы избежать комбинации этих двух аннотаций, заключается в том, что вы должны применить Retryable
на самом внешнем Transactional
в цепочке вызовов, чтобы убедиться, что вы получаете новую транзакцию (это также означает, что перехватчик повторных попыток должен быть применен первым). Если у вас есть метод Transactional
, который иногда создает транзакцию, а иногда присоединяется к транзакции, вы не можете добавить Retryable
, поэтому вам придется создать две версии метода (одну с Propagation.MANDATORY и без повторных попыток). и один с повтором) - это похоже на большую ручную работу, и источник ошибки
Мне нужен общий механизм, который автоматически повторяет ObjectOptimisticLockingFailureException несколько раз. Я могу подумать о некоторых возможностях
- Переконфигурировать
Transactional
, чтобы повторить 3 раза - Создать новую аннотацию, которая объединяет логики c из
TransactionInterceptor
и RetryOperationsInterceptor`. - Что-то умнее (прибыль)
Мы также используем TransactionTemplate
, и я смог заменить реализацию по умолчанию своим собственным подклассом, используя BeanPostProcessor
, так что я могу получить automati c retry.
Однако логика Interceptor c, используемая с Transactional
, намного сложнее. Я попытался добавить дополнительный Aspect
таргетинг Transactional
, но он не работает, и даже если бы он это сделал, он мог найти оригинальный компонент службы вместо Proxy, который добавляет поддержку транзакций. В идеале я хотел бы вставить перехватчик попыток между PersistenceExceptionTranslator
и TransactionInterceptor
, кто-нибудь знает, как это сделать?