2010-06-15 3 views
3

this article에 따라 Spring + Hibernate 용 Dynamic DataSource Routing을 구현했습니다. 같은 구조의 여러 데이터베이스가 있고 각 특정 쿼리를 실행할 db를 선택해야합니다.AbstractRoutingDataSource에 대해 안전한 데이터 소스 스위치를 자주 만드는 방법은 무엇입니까?

모든 것이 로컬 호스트에서 제대로 작동하지만 실제 웹 사이트 환경에서 이것이 어떻게 유지 될지 걱정됩니다. 그들은 사용할 데이터 소스를 결정하기 위해 몇 가지 정적 컨텍스트 홀더를 사용하고 있습니다 :

public class CustomerContextHolder { 

    private static final ThreadLocal<CustomerType> contextHolder = 
      new ThreadLocal<CustomerType>(); 

    public static void setCustomerType(CustomerType customerType) { 
     Assert.notNull(customerType, "customerType cannot be null"); 
     contextHolder.set(customerType); 
    } 

    public static CustomerType getCustomerType() { 
     return (CustomerType) contextHolder.get(); 
    } 

    public static void clearCustomerType() { 
     contextHolder.remove(); 
    } 
} 

그것은 일부의 ThreadLocal 용기 내부에 싸여있다,하지만 정확히 무엇을 의미 하는가?

CustomerContextHolder.setCustomerType(CustomerType.GOLD); 
//<another user will switch customer type here to CustomerType.SILVER in another request> 
List<Item> goldItems = catalog.getItems(); 

스프링 MVC에서 자체 스레드에 랩 모든 웹 요청입니다 : 두 개의 웹 요청이 병렬로이 코드 조각을 호출 할 때 어떻게됩니까? CustomerContextHolder.setCustomerType() 변경 사항이 다른 웹 사용자에게 표시됩니까? 내 컨트롤러는 synchronizeOnSession=true입니다.

현재 사용자에게 필요한 쿼리를 실행할 때까지 아무도 데이터 소스를 전환하지 않도록하려면 어떻게해야합니까?

감사합니다.

+0

나는 괜찮을 것이라고 생각한다. 각 서블릿 요청은 단일 스레드에서 실행됩니다 (그리고 Spring은 바로 밑의 서블릿입니다). 최대 절전 모드 샤드 사용을 고려 했습니까? –

답변

5

모든 웹 요청은 Spring MVC에서 자체 스레드로 래핑됩니까?

예,하지만 이것은 Spring MVC와는 아무런 관련이 없습니다. 컨테이너가이를 수행하고 있습니다 (컨테이너에는 스레드 풀이 있으며 각 요청을 처리하기 위해 그 중 하나를 선택합니다).

다른 웹 사용자가 CustomerContextHolder.setCustomerType() 변경 사항을 볼 수 있습니까?

No. A ThreadLocal은 정의 적으로 스레드에 국한됩니다. javadoc에서 :

이 클래스는 스레드 로컬 변수를 제공합니다. 이러한 변수는 하나의 변수에 액세스하는 각 스레드 (그 get 또는 set 메소드를 통해)가 독립적으로 초기화 된 변수 사본을 가지고 있다는 점에서 일반 변수와 다릅니다. ThreadLocal 인스턴스는 일반적으로 스레드와 상태 (예 : 사용자 ID 또는 트랜잭션 ID)를 연결하려는 클래스의 개인 정적 필드입니다.

ThreadLocal에서 무엇을 set을 다른 스레드가 볼 수 없습니까? 너 괜찮을거야

관련 문제