시나리오 : Websphere에서 실행되는 Spring 관리 웹 응용 프로그램이 있습니다. (Spring 3.0.x, WAS 7) webapp는 Spring의 WorkManagerTaskExecutor
(스레드 풀 크기가 10으로 구성된)을 통해 Websphere의 작업 관리자를 활용하여 계산 집약적 인 db 읽기 작업을 실행합니다. 그래서 기본적으로 10 개의 서로 다른 문서를 생성하는 요청이 들어옵니다. 문서를 생성하려면 데이터를 수집/처리하는 데 db 읽기 만 필요합니다. 그래서 우리는 기본적으로 10 개의 문서를 처리하기 위해 10 개의 스레드를 생성하고 마지막에는 10 명의 작업자가 반환 한 10 개의 문서를 모아서 병합하고 하나의 커다란 응답을 클라이언트에게 되돌려 씁니다. 우리가 확인한 바에 따르면 10 개의 스레드가 데이터를 수집/처리하는 동안 유사한 db 호출이 많이 발생했습니다. 그래서 우리가 생각해 낸 것은 응답을 캐싱하기 위해 가장 많이 실행 된 db 메소드를 중심으로 Aspect를 만드는 것입니다. 애스펙트는 싱글 톤으로 구성되며 애스펙트가 사용하는 캐시는 범위가 요청 범위로 설정된 aspect에 자동으로 요청되어 각 요청에 자체 캐시가 있습니다.다중 스레드 웹 응용 프로그램에서 요청 범위 Bean에 액세스
문제 : 이제이 방법의 문제점은 스레드가 db 호출을 수행하고 있고 Aspect가 끼어들 때 java.lang.IllegalStateException: No thread-bound request found
예외가 발생한다는 것입니다. 스레드가 요청 컨텍스트 외부에서 실행될 때 완전히 이해됩니다.
이 문제를 쉽게 탐색 할 수있는 방법이 있습니까? 요청 범위 캐시가있는 애스펙트를이 스레드가 호출하는 메소드에 적용 할 수 있습니까?
(물론, 비동기 방식을 사용하면 요청 스레드에서의 결과를 수집 할 수 있도록
Future<Result>
를 반환해야합니다),하지만 난 찾을 하나의 단점은 이렇게 되었 저를 강제하는 것입니다 캐시하려는 모든 메소드 호출 (스레드 실행 중)의 고유 요청 식별자 다운 스트림. 또한 캐시가 잠시 후에 꽤 크게되지 않을까요? 그런 다음 주기적으로 관리해야합니다. 어쩌면 여기서 뭔가를 놓칠 수 있습니다. – r4j1v아마도 내 고유 요청 식별자를 저장하고 그것을 직접 전달하지 않고도 측면에서 검색 할 수있는 "스레드 실행 컨텍스트"가 있습니까? – r4j1v
나는이 문제를 해결할 수 있었다. 나는'WorkManagerTaskExecutor' 대신'SimpleAsyncTaskExecutor'를 사용하기 시작했습니다. 이점은'SimpleAsyncTaskExecutor'는 스레드를 결코 다시 사용하지 않는다는 것입니다. 솔루션의 절반에 불과합니다. 나머지 절반은'RequestContextListener' 대신'RequestContextFilter'를 사용하는 것입니다. 'RequestContextFilter'는 기본적으로 자식 스레드가 부모 컨텍스트를 상속 할 수있게 해주는'setThreadContextInheritable()'메소드를 가지고 있습니다. – r4j1v