場景: 我們有一個在Websphere內運行的Spring託管Web應用程序。 (Spring 3.0.x,WAS 7) Web應用程序通過Spring的WorkManagerTaskExecutor
(配置爲線程池大小爲10)利用Websphere的工作管理器來執行計算密集型數據庫讀取操作。所以基本上,一個請求來生成,可以說,10個不同的文件。要生成文檔,只需要db讀取來收集/處理數據。所以我們基本上產生了10個線程來處理10個文檔,最後收集10個工作人員返回的10個文檔,併合並它們,並向客戶端寫回一個大的響應。我們發現,雖然10個線程正在收集/處理數據,但還是有大量類似的db調用。所以我們想出的是圍繞最執行的數據庫方法創建一個方面來緩存響應。該方面被配置爲單例,並且該方面使用的緩存被自動裝配到方面,其範圍設置爲請求範圍,以便每個請求都有自己的緩存。在多線程Web應用程序中訪問請求範圍的bean
問題: 現在這種方法的問題是,當線程正在做他們的數據庫調用和方面是interjects我們得到java.lang.IllegalStateException: No thread-bound request found
異常。我的理解是完全有效的,因爲線程在請求上下文之外執行。
有沒有辦法繞開這個問題?是否有可能將請求範圍緩存的方面應用於這些線程所調用的方法?
我想到的辦法,但有一個缺點,我覺得是,它會迫使我傳球在我想要緩存的所有方法調用的下游(在線程執行期間)的唯一請求標識符。另外,一段時間後緩存會不會很大?這會迫使我定期進行管理。也許我在這裏錯過了一些東西。 – r4j1v
也許有一個「線程執行上下文」,我可以使用它來存儲我的唯一請求標識符並在方面檢索它,而不必自己傳遞它? – r4j1v
我設法解決了這個問題。我開始使用'SimpleAsyncTaskExecutor'而不是'WorkManagerTaskExecutor'。好處是'SimpleAsyncTaskExecutor'永遠不會重用線程。這只是解決方案的一半。解決方案的另一半是使用'RequestContextFilter'而不是'RequestContextListener'。 'RequestContextFilter'有一個'setThreadContextInheritable()'方法,它基本上允許子線程繼承父上下文。 – r4j1v