Scenariusz: Mamy aplikację internetową zarządzaną przez Spring, która działa w sieci Websphere. (Wiosna 3.0.x, WAS 7) Aplikacja webowa wykorzystuje menedżera pracy Websphere za pośrednictwem Spring WorkManagerTaskExecutor
(skonfigurowany z pulą wątków o wielkości 10) w celu wykonywania intensywnych obliczeń operacji odczytu bazy danych. Zasadniczo pojawia się żądanie wygenerowania, powiedzmy, 10 różnych dokumentów. Do generowania dokumentów potrzebne są tylko odczyty db do zbierania/przetwarzania danych. Zasadniczo odradzamy 10 wątków, aby przetworzyć 10 dokumentów, a na końcu zebrać 10 dokumentów zwróconych od 10 pracowników i połączyć je i odpisać jedną dużą odpowiedź dla klienta. Zidentyfikowaliśmy, że podczas gdy 10 wątków zbiera/przetwarza dane, powstaje wiązka podobnych wywołań db. Więc stworzyliśmy Aspekt wokół najczęściej wykonywanych metod db do buforowania odpowiedzi. Aspekt jest skonfigurowany jako singleton, a pamięć podręczna, której używa aspekt, jest automatycznie przekształcana w aspekt z zakresem ustawionym na request-scope, tak aby każde żądanie miało własną pamięć podręczną.Uzyskiwanie dostępu do komponentu bean o żądanej liczbie zapytań w wielowątkowej aplikacji internetowej
Problem: Problem z tym podejściem polega na tym, że gdy wątki wykonują swoje wywołania db, a Aspekt jest wtrącany, otrzymujemy wyjątek java.lang.IllegalStateException: No thread-bound request found
. Rozumiem, że jest to całkowicie prawidłowe, ponieważ wątki są wykonywane poza kontekstem żądania.
Czy istnieje sposób na obejście tego problemu? Czy możliwe jest zastosowanie aspektu z pamięcią podręczną o zakresie zapytań do metod wywoływanych przez te wątki?
myślałem o podejściu, ale jedna wada, że uważam, że zmusi mnie do przejść unikalny identyfikator żądania poniżej wszystkich wywołań metod (podczas wykonywania wątku), które chciałbym buforować. Czy pamięć podręczna po pewnym czasie nie stałaby się naprawdę duża? Co zmusiłoby mnie do okresowego zarządzania. Może czegoś tu brakuje. – r4j1v
Być może istnieje "kontekst wykonania wątku", który mogę wykorzystać do przechowywania mojego unikalnego identyfikatora żądania i pobrania go w aspekcie bez konieczności przekazywania go samemu? – r4j1v
Udało mi się ominąć ten problem. Zacząłem używać 'SimpleAsyncTaskExecutor' zamiast' WorkManagerTaskExecutor'. Korzyścią jest to, że 'SimpleAsyncTaskExecutor' nigdy nie użyje ponownie wątków. To tylko połowa rozwiązania. Drugą połową rozwiązania jest użycie 'RequestContextFilter' zamiast' RequestContextListener'. 'RequestContextFilter' ma metodę' setThreadContextInheritable() ', która zasadniczo umożliwia wątkom potomnym dziedziczenie kontekstu nadrzędnego. – r4j1v