복붙노트

[SPRING] 다중 스레드 웹 응용 프로그램에서 요청 범위 Bean에 액세스

SPRING

다중 스레드 웹 응용 프로그램에서 요청 범위 Bean에 액세스

대본: 우리는 Websphere 내에서 실행되는 Spring 관리 웹 애플리케이션을 가지고있다. (Spring 3.0.x, WAS 7) webapp은 Spring의 WorkManagerTaskExecutor (스레드 풀 크기가 10으로 설정 됨)를 통해 Websphere의 작업 관리자를 활용하여 계산 집약적 인 db 읽기 작업을 실행합니다. 그래서 기본적으로 10 개의 서로 다른 문서를 생성하라는 요청이 들어옵니다. 문서를 생성하려면 데이터를 수집 / 처리하는 데 db read가 필요합니다. 그래서 우리는 기본적으로 10 개의 문서를 처리하기 위해 10 개의 스레드를 생성하고 마지막에는 10 명의 작업자로부터 반환 된 10 개의 문서를 모아서 병합하고 하나의 커다란 응답을 클라이언트에게 되돌려 씁니다. 우리가 확인한 바에 따르면 10 개의 스레드가 데이터를 수집 / 처리하는 동안 비슷한 db 호출이 많이 발생했습니다. 그래서 우리가 생각해 낸 점은 응답을 캐시하기 위해 가장 많이 실행 된 db 메소드를 중심으로 Aspect를 만드는 것입니다. 애스펙트는 싱글 톤으로 구성되며 애스펙트가 사용하는 캐시는 스코프가 요청 범위로 설정된 aspect에 자동으로 연결되어 각 요청에 자체 캐시가 있습니다.

문제: 이제이 접근법의 문제점은 쓰레드가 db 호출을 수행하고 Aspect가 삽입 될 때 java.lang.IllegalStateException : thread-bound request가 발견되지 않는다는 것입니다. 스레드가 요청 컨텍스트 외부에서 실행될 때 완전히 이해됩니다.

이 문제를 해결할 수있는 방법이 있습니까? 요청 범위 캐시가있는 aspect를이 스레드에 의해 호출 된 메소드에 적용 할 수 있습니까?

해결법

  1. ==============================

    1.나는 너가 이것을 직접 할 수 있다고 생각하지 않는다. 당신이 할 수 있었다하더라도, 그것은 약간 추한 것입니다. 그러나 고유 한 요청 식별자를 생성 할 수 있습니다 (또는 심지어 세션 ID를 사용하지만 여러 탭에주의해야 함). 그리고 각 처리 스레드로 전달하십시오. 그런 다음 애스펙트는 해당 ID를 캐시의 키로 사용할 수 있습니다. 캐시 자체도 싱글 톤이지만 Map 이있을 것입니다. 여기서 String은 ID이고 X는 캐시 된 결과입니다.

    나는 너가 이것을 직접 할 수 있다고 생각하지 않는다. 당신이 할 수 있었다하더라도, 그것은 약간 추한 것입니다. 그러나 고유 한 요청 식별자를 생성 할 수 있습니다 (또는 심지어 세션 ID를 사용하지만 여러 탭에주의해야 함). 그리고 각 처리 스레드로 전달하십시오. 그런 다음 애스펙트는 해당 ID를 캐시의 키로 사용할 수 있습니다. 캐시 자체도 싱글 톤이지만 Map 이있을 것입니다. 여기서 String은 ID이고 X는 캐시 된 결과입니다.

    일을 더 쉽게 처리하기 위해 스레드를 수동으로 생성하는 대신 @Async 메서드를 사용할 수 있으며 각 @Async 메서드는 첫 번째 매개 변수로 전달 된 캐시 ID를 가질 수 있습니다.

    (물론 비동기 메서드는 요청 스레드에서 결과를 수집 할 수 있도록 Future 를 반환해야합니다.)

  2. from https://stackoverflow.com/questions/7638003/accessing-request-scoped-beans-in-a-multi-threaded-web-application by cc-by-sa and MIT license