2012-05-17 8 views
0

스프링 mvc 애플리케이션에서 프런트 엔드에서 사용자가 선택한 기능을 기반으로 주어진 시간에 여러 데이터베이스에 연결해야합니다. 우리가 가정 해 봅시다 :Spring MVC에서 다중 데이터 소스 관리하기

1.I 3 개 서로 다른 환경 (PROD, PRE-PROD 및 준비 등 ...)

2. 사용자는 주어진 데이터베이스에서 테이블의 목록을보고 싶어 있습니다. 사용자가 선택 상자에서 항목을 선택하여 제출합니다. 사용자 선택에 따라 각 데이터베이스에 연결하여 결과를 얻어야합니다.

3.Some 시간은 데이터베이스의 일부가 다운 할 수 있습니다 나는 각 데이터베이스에 대해 JNDI 데이터 소스를 작성하고 JdbcTemplate을에 매핑이 모든 jdbcTemplaates이

<bean id="prodDataSource" ref="prodDSPool"/> 
<bean id="preProdDataSource" ref="preProdDSPool"/> 
<bean id="statgingDataSource" ref="stagingDSPool" /> 
... 
... 

처럼 내 DAO에 속성으로 정의 된 경우 그리고 나는 다른 아무것도없는 빈하지만 내 DAO

<bean id="myConnectionsDAO" class="com.example.MyConnectionsDAOImpl"> 
     <property name="prodDataSource"> 
      <ref bean="prodDataSource"/> 
     </property> 
     <property name="preProdDataSource"> 
      <ref bean="preProdDataSource"/> 
     </property> 
     <property name="preProdDataSource"> 
      <ref bean="preProdDataSource"/> 
     </property> 
</bean> 

을 그리고 MyConnectionDAO 위의 속성에 대한 게터와 세터와 POJO이다.

제가 위에서 말했듯이 내 서비스 클래스는 관련 데이터 소스를 가져 와서 JdbcTemplate을을 구축하고

if(env.equalsIgnoreCase(EnvEnum.PROD.toString()) 
{ 
    JdbcTemplate prodTemplate = new JdbcTemplate(myConnectionsDAO.getProdDataSource()); 
prodTemplate.queryForList("select name form sysibm.systables where creator='admin'); 
//Core business logic to analyze those tables and proceed... 
}else if {//preprod logic} else if{//staging logic} 

같은 데이터베이스를 쿼리 사용자의 선택에 따라 그리고 DB2 데이터베이스에서 데이터를 주위 재생 복잡한 기능을 많이 가지고 . 데이터 소스를 주입 할 때부터 spring config를 사용하여 DAO에 속성을 추가합니다. 어떤 이유로 든 하나의 데이터베이스/데이터 소스가 다운 된 경우 하나 이상의 데이터 소스가 다운 되었기 때문에 내 애플리케이션을 사용할 수없고 nullpointer를 가져올 수 없습니다.

어떻게 이러한 오류를 처리 할 수 ​​있습니까? 기본적으로 나는 적어도 하나의 ds가 있다면 내 애플 리케이션을 실행하고 싶습니다. 그리고 위의 설정을 사용하여 약 50 개의 데이터베이스를 구성했습니다.

저는이 문제를 해결하는 방법에 대해 거의 혼란스럽지 않고 실마리를 얻지 못했습니다. 사전에 감사드립니다 ...

답변

0

기본적으로 데이터베이스마다 자신의 Spring Application Context를 관리해야합니다.

해당 데이터베이스에 대한 루트 application context의 하위 항목으로 응용 프로그램 컨텍스트를 시작합니다. 앞으로 동적 db/datasource 애플리케이션 컨텍스트의 라이프 사이클을 관리해야 할 것입니다.

다른 옵션은이 라우팅을 자동으로 백그라운드에서 수행하는 사용자 정의 단일 Datasource을 작성하는 것입니다. 귀하의 편집 내용에 따라 가장 좋은 옵션으로 보입니다.

public class RoutingDatasource implements DataSource, ApplicationContextAware { 

    private volatile DataSource realDataSource; 
    private ApplicationContext ac; 

    // You must do some thread locking here that will be rather complicated. 
    // That is not included in this example 
    public void switchDatasource(String name) { 
     this.realDataSource = this.ac.getBean(name, DataSource.class); 
    } 

    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
     this.ac = applicationContext; 
    } 

    // delegate to realDataSource 


} 

안전하게 데이터 소스 개체를 잠그는 방법을 알아야합니다. 나는 너를 위해 그것을 떠날 것이다 (미안해.).

+0

같은 코드 샘플을 제공 할 수 있습니까? 맞춤 데이터 소스를 작성하고 더 많은 데이터베이스에 대한 지원을 추가해야하는 경우 수업을 편집 할 때마다 번거로울 수 있습니다. 스프링은 상자를 꺼내서 처리 할 수있는 메커니즘을 제공합니까? – springpress

+0

사용자 정의 데이터 소스는 스프링을 인식합니다. ApplicationContextAware를 참조하십시오. 아마 당신은 당신이 applicationContext.getBean()과 같은 일을하는 당신의 라우팅 데이터 소스에서 실제 데이터 소스에 대한 명명 스키마를 제안 할 수 있습니다. –

+0

당신은 내가 TransactionAwareDataSourceProxy를 구현하여 스키마 전환을 위해서만 내 사용자 정의 데이터 소스를 작성했으나 어떤 경우에는 하나의 데이터베이스에서 메타 데이터를 가져 와서 다른 db의 값을 검증하기 위해 두 개 이상의 다른 데이터베이스가 필요합니다. 이 경우 RoutingDataSource 솔루션을 사용할 수 없습니다. 탁신 – springpress

관련 문제