Spring @Async和AbstractRoutingDataSource

时间:2011-09-06 20:02:37

标签: multithreading hibernate spring jdbc asynchronous

我一直在使用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,因此它会在其他任何内容之前被触发。

enter image description here

1 个答案:

答案 0 :(得分:2)

认为我找到了答案:方法执行拦截将无法在ThreadLocal上设置变量,因为AsyncExecutionInterceptor将始终具有更高的优先级并启动Hibernate事务。相反,我所做的是将逻辑从异步方法外部化到它自己的类,并通过@Transactional(propagation=Propagation.REQUIRES_NEW)将该方法标记为需要自己的事务。由于子方法现在在自己的事务中运行,ThreadLocal上的变量在新的Hibernate事务开始时被AbstractRoutingDataSource正确选取。