2011-09-06 14 views
5

He estado usando el AbstractRoutingDataSource con gran éxito, pero han dado con un problema que no puedo resolver: cuando me quito un método asíncrono utilizando @Async, pierde el contexto del subproceso local y No puedo entender el lugar para configurar el cambio de contexto de la base de datos. Normalmente lo hago en un aspecto o en un HandlerInterceptor, pero @Async no pasa por ninguna de esas rutas habituales. ¿Hay un interceptor o algo similar que pueda configurar para disparar al principio y al final de la llamada de asincronización para que pueda establecer el contexto de la base de datos?primavera @Async y la AbstractRoutingDataSource

He encontrado una pregunta similar en los foros de mensajes de primavera. No hubo respuesta, sin embargo: http://forum.springsource.org/showthread.php?83792-Async-annotated-method-hanging-on-session-scoped-bean

EDIT: He depurado el flujo de ejecución, y la fuente AbstractRoutingData está, de hecho, consiguiendo llamada en el hilo asíncrono, pero su recibiendo llamadas antes de que el aspecto está recibiendo llamadas, por lo que el DataSource ya está configurado en la sesión de Hibernate antes de se está estableciendo el valor ThreadLocal. Mirando el código fuente para AsyncExecutionInterceptor, que respalda @Async, es porque el interceptor devuelve su valor Order como , por lo que es despedido antes que cualquier otra cosa.

enter image description here

Respuesta

2

Creo que he encontrado la respuesta: método de ejecución intercepción fallará para establecer la variable en la ThreadLocal, como el AsyncExecutionInterceptor siempre tendrá mayor precedencia y empezar la operación de hibernación. En cambio, lo que hice fue externalizar la lógica del método async a su propia clase, y marqué ese método como que requiere su propia transacción, a través del @Transactional(propagation=Propagation.REQUIRES_NEW). Dado que el submétodo ahora se ejecuta en su propia transacción, la variable en el ThreadLocal se recoge correctamente en el AbstractRoutingDataSource al inicio de la nueva transacción de Hibernate.