7 votes

Printemps @Async et AbstractRoutingDataSource

J'ai utilisé le AbstractRoutingDataSource avec grand succès, mais j'ai rencontré un problème que je ne peux pas résoudre : lorsque je lance une méthode asynchrone en utilisant @Async, elle perd le contexte local du thread, et je ne parviens pas à déterminer l'endroit où définir le changement de contexte de base de données. Habituellement, je le fais dans un aspect ou dans un HandlerInterceptor, mais @Async ne passe par aucune de ces routes habituelles. Y a-t-il un intercepteur ou quelque chose de similaire que je peux configurer pour se déclencher au début et à la fin de l'appel asynchrone afin de pouvoir définir le contexte de base de données ?

J'ai trouvé une question similaire sur les forums de discussion de Spring. Pas de réponse, cependant : http://forum.springsource.org/showthread.php?83792-Async-annotated-method-hanging-on-session-scoped-bean

MODIFIER : J'ai débogué le flux d'exécution, et la source de données AbstractRoutingData est en fait appelée dans le thread asynchrone, mais elle est appelée avant que l'aspect ne soit appelé, donc le DataSource est déjà défini dans la session Hibernate avant que la valeur de ThreadLocal ne soit définie. En regardant le code source de AsyncExecutionInterceptor, qui prend en charge @Async, c'est parce que l'intercepteur retourne sa valeur Order en tant que HIGHEST_PRECEDENCE, donc il est déclenché avant tout le reste.

description de l'image ici

3voto

atrain Points 5653

Je pense avoir trouvé la réponse : l'interception de l'exécution de la méthode échouera à définir la variable sur le ThreadLocal, car l'intercepteur AsyncExecutionInterceptor aura toujours une priorité plus élevée et démarrera la transaction Hibernate. Au lieu de cela, ce que j'ai fait, c'est externaliser la logique de la méthode asynchrone dans sa propre classe, et marquer cette méthode comme nécessitant sa propre transaction, via @Transactional(propagation=Propagation.REQUIRES_NEW). Puisque la sous-méthode s'exécute maintenant dans sa propre transaction, la variable sur le ThreadLocal est correctement récupérée par l'AbstractRoutingDataSource au début de la nouvelle transaction Hibernate.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X