Какова наилучшая практика реализации перезагрузки транзакций при исключениях блокировки или блокировки таймаута при использовании Spring (в частности, рекомендуемый подход Spring: декларативные транзакции)?
Спасибо,
Асаф
Какова наилучшая практика реализации перезагрузки транзакций при исключениях блокировки или блокировки таймаута при использовании Spring (в частности, рекомендуемый подход Spring: декларативные транзакции)?
Спасибо,
Асаф
Мне кажется, что сам Spring должен иметь хороший ответ на этот вопрос (в виде документации, по крайней мере, или какого-то перехватчика повторных попыток). Увы, это не так.
Вероятно, лучший способ обработки повторных попыток (если вы хотите продолжать "декларативный" о вещах) заключается в том, чтобы написать собственную реализацию перехватчика, которая будет автоматически повторять транзакцию сконфигурированное количество раз. Для начала изучите Spring TransactionInterceptor
, который управляет началом/откатом/фиксацией поведения для декларативных транзакций. Если вы используете Hibernate, обратите внимание на то, как он обрабатывает привязку/отключение привязки Hibernate к текущему потоку.
Остерегайтесь, если вы используете Hibernate:
session.clear()
недостаточно).MethodInterceptor.invoke()
- экземпляр MethodInvocation
, который будет передан в это, может быть с сохранением состояния; вам может понадобиться клонировать его перед использованием в перехватчике.Я рекомендую использовать класс org.springframework.retry.interceptor.RetryOperationsInterceptor
из проекта spring retry , настроенного как это:
<aop:config>
<aop:pointcut id="transactional" expression="execution(* com...*Service.remoteCall(..))" />
<aop:advisor pointcut-ref="transactional" advice-ref="retryAdvice" order="-1"/>
</aop:config>
<bean id="retryAdvice" class="org.springframework.retry.interceptor.RetryOperationsInterceptor"/>
Но если вы все еще хотите реализовать его самостоятельно, хороший пример AOP из spring документации.
Нет универсального ответа, поскольку он зависит от специфики приложения. Например, вы можете выполнить автоматический перезапуск транзакции или уведомить пользователя об ошибке работы и запросить явное подтверждение повтора и т.д.
Я бы использовал AOP в случае автоматического перезапуска.
У меня был тот же вопрос несколько лет назад, и я написал мое собственное решение как аспект AOP, который заканчивается таким, как это в вашем код:
@RetryTransaction
@Transactional
public void doSomething() {
....
}