场景: 我们有一个在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