我一直在使用AbstractRoutingDataSource取得了巨大成功,但遇到了一个我无法解决的问题:当我使用@Async
启动异步方法时,它会丢失本地线程的上下文,我无法弄清楚设置数据库上下文切换的地方。通常我会在一个方面或HandlerInterceptor
中进行,但@Async
不会通过任何常规路线。是否有一个拦截器或类似的东西,我可以配置为在异步调用的开始和结束时触发,以便我可以设置数据库上下文?
在Spring留言板上发现了类似的问题。但是没有答案:http://forum.springsource.org/showthread.php?83792-Async-annotated-method-hanging-on-session-scoped-bean
编辑:我已经调试了执行流程,并且AbstractRoutingData源实际上是实际上是在异步线程中调用的,但是在调用方面之前调用它,所以{{1已经在Hibernate会话之前设置DataSource
值已设置。查看支持ThreadLocal
的{{1}}的源代码,因为拦截器将其AsyncExecutionInterceptor
值返回为@Async
,因此它会在其他任何内容之前被触发。
答案 0 :(得分:2)
认为我找到了答案:方法执行拦截将无法在ThreadLocal
上设置变量,因为AsyncExecutionInterceptor
将始终具有更高的优先级并启动Hibernate事务。相反,我所做的是将逻辑从异步方法外部化到它自己的类,并通过@Transactional(propagation=Propagation.REQUIRES_NEW)
将该方法标记为需要自己的事务。由于子方法现在在自己的事务中运行,ThreadLocal
上的变量在新的Hibernate事务开始时被AbstractRoutingDataSource
正确选取。