1

We are using @Async for multithreading. Untill each multithreading method i can see values for RequestContextHolder.getRequestAttributes().

But when i debug inside the method i'm getting request attributes as NULL.

Any thoughts?

universe
  • 99
  • 1
  • 2
  • 7

2 Answers2

2

To get around this issue we created a ContextAwareRunnable Object that was pre-populated with the current requestHolder, securityContextHolder, etc, so that all spawned threads would be able to execute as if it were running in the main thread.

Dan
  • 979
  • 1
  • 8
  • 29
  • Dan, can you please elaborate a bit more about that? Also, may i know why once Async method starts RequestAttributes are vanishing (Is that because of newly created thread)? Thanks! – universe Aug 22 '18 at 20:06
  • @universe - Yes, the new thread has not been populated with any of the request details from the main thread. – Dan Aug 22 '18 at 20:09
  • If you need those details, I'd run the method calls from an ExecutorService instead of marking the methods @Async. – Dan Aug 22 '18 at 20:10
  • Thanks. But, i don't think i can change method calls (That will be a major change). Anyway can we set those request details to all spawned threads before @Async? – universe Aug 22 '18 at 20:13
  • Why can't you change up how your method is being called. It's as simple as a single line of code `executor.submit(() -> YourClass.methodName(), contextAwareExecutor);` – Dan Aug 22 '18 at 20:16
  • We are not using executor.submit. We implemented async framework using Spring Annotations. https://www.baeldung.com/spring-async – universe Aug 23 '18 at 01:57
  • Goodluck with it – Dan Aug 23 '18 at 02:52
  • Thank you @Dan. universe you want to check out this link for implementation, https://stackoverflow.com/questions/23732089/how-to-enable-request-scope-in-async-task-executor – wolf97084 May 22 '19 at 17:48
2

By default ThreadLocal variable is used as holder for request attributes. That means that only single thread which handles entire https request is able to access request attributes. In contrast @Async methods are processed by threads from a separate thread pool so they can't access the attributes.

However there is one more InheritableThreadLocal variable which could be used as request attributes holder instead for default one. You can enabled it by setting threadContextInheritable property to true in DispatcherServlet or RequestContextFilter.

Take a look at implementation of RequestContextHolder for more details.

Mikita Harbacheuski
  • 2,193
  • 8
  • 16