Quelle est la meilleure pratique pour mettre en œuvre un redémarrage de transaction en cas d’interblocage ou d’exception de délai de locking lors de l’utilisation de Spring (en particulier de l’approche recommandée par Spring: transactions déclaratives)?
Merci,
Asaf
Je pense que Spring lui-même devrait avoir une bonne réponse à cette question (sous forme de documentation, au moins, ou d’un intercepteur de relance quelconque). Hélas, ce n’est pas le cas.
Le meilleur moyen de gérer les tentatives (si vous voulez continuer à être “déclaratif” à propos de choses) est d’écrire votre propre implémentation d’intercepteur qui réessayera automatiquement la transaction un nombre de fois configuré. Pour commencer, étudiez le TransactionInterceptor
de Spring, qui gère le comportement start / rollback / commit pour les transactions déclaratives. Si vous utilisez Hibernate, notez la manière dont il gère la liaison / dissociation de session Hibernate avec le thread en cours.
A surveiller si vous utilisez Hibernate:
session.clear()
n’est pas suffisant.) MethodInterceptor.invoke()
– l’instance MethodInvocation
qui est transmise à ceci peut être stateful; vous devrez peut-être le cloner avant de l’utiliser dans l’intercepteur. Je recommande d’utiliser la classe org.springframework.retry.interceptor.RetryOperationsInterceptor
partir du projet de nouvelle tentative, configurée comme org.springframework.retry.interceptor.RetryOperationsInterceptor
:
Mais si vous souhaitez toujours le mettre en œuvre vous-même, l’ exemple de la documentation de spring de AOP est un bon début.
Il n’y a pas de réponse universelle car cela dépend des spécificités de l’application. Par exemple, vous pouvez effectuer un redémarrage automatique de l’opération de transaction ou informer l’utilisateur de l’échec de l’opération et demander une confirmation explicite de la nouvelle tentative, etc.
J’utiliserais AOP en cas de scénario de redémarrage automatique.
J’ai eu la même question il y a plusieurs années et j’ai fini par écrire ma propre solution en tant qu’aspect AOP, qui finit par ressembler à ceci dans votre code:
@RetryTransaction @Transactional public void doSomething() { .... }