2011-09-06 100 views
5

我一直在使用AbstractRoutingDataSource取得了巨大成功,但遇到了一個我無法解決的問題:當我使用@Async啓動異步方法時,它會丟失本地線程的上下文,並且我找不到設置數據庫上下文切換的地方。通常我會在某個方面或在HandlerInterceptor中執行此操作,但@Async不會執行任何這些常規路徑。是否有一個攔截器或類似的東西可以配置爲在異步調用的開始和結束時觸發,以便我可以設置數據庫上下文?Spring @Async和AbstractRoutingDataSource

在Spring留言板上發現了類似的問題。沒有答案,但:http://forum.springsource.org/showthread.php?83792-Async-annotated-method-hanging-on-session-scoped-bean

編輯:我調試的執行流程,以及AbstractRoutingData源其實是在得到所謂的異步線程,但它獲取調用獲取調用方面之前,所以DataSource已經設置在Hibernate會話之前ThreadLocal值已設置。查看AsyncExecutionInterceptor的源代碼,該代碼支持@Async,其原因是攔截器將其Order的值返回爲,因此它在其他任何事情之前被解僱。

enter image description here

回答

2

想我已經找到了答案:方法執行攔截將無法設置在ThreadLocal變量,因爲AsyncExecutionInterceptor總是有更高的優先級,並啓動Hibernate事務。相反,我所做的是將異步方法的邏輯外化爲其自己的類,並通過@Transactional(propagation=Propagation.REQUIRES_NEW)將該方法標記爲需要自己的事務。由於子方法現在在自己的事務中運行,所以ThreadLocal上的變量在新Hibernate事務開始時被AbstractRoutingDataSource正確拾取。