Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Async and the AbstractRoutingDataSource

I've been using the AbstractRoutingDataSource with great success, but have hit upon an issue I can't resolve: when I kick off an asynchronous method using @Async, it loses the local thread's context, and I can't figure out the place to set the database context switch. Usually I do it an aspect or in a HandlerInterceptor, but @Async doesn't go through any of those usual routes. Is there an interceptor or something similar I can configure to fire at the beginning and end of the asynch call so that I can set the database context?

Found a similar question on the Spring message boards. No answer, though: http://forum.springsource.org/showthread.php?83792-Async-annotated-method-hanging-on-session-scoped-bean

EDIT: I've debugged the execution flow, and the AbstractRoutingData source is in fact getting called in the async thread, but its getting called before the aspect is getting called, so the DataSource is already set in the Hibernate session before the ThreadLocal value is getting set. Looking at the source code for AsyncExecutionInterceptor, which backs @Async, its because the interceptor returns its Order value as HIGHEST_PRECEDENCE, so its getting fired before anything else.

enter image description here

like image 431
atrain Avatar asked Sep 06 '11 20:09

atrain


1 Answers

Think I've found the answer: method execution interception will fail to set the variable on the ThreadLocal, as the AsyncExecutionInterceptor will always have higher precedence and start the Hibernate transaction. Instead, what I've done is externalized the logic from the async method to its own class, and marked that method as requiring its own transaction, via @Transactional(propagation=Propagation.REQUIRES_NEW). Since the sub-method now runs in its own transaction, the variable on the ThreadLocal is correctly picked up by the AbstractRoutingDataSource at the onset of the new Hibernate transaction.

like image 108
atrain Avatar answered Sep 20 '22 08:09

atrain