Jsp-Servlet/Spring

Spring mybatis 다중 DB를 사용하는 방법

seongsland 2018. 3. 27. 15:55

Spring mybatis 다중 DB를 사용하는 방법

1. dataSource를 여러개 만들고 sqlMapClient도 여러개 만든다.

<!-- dataSource -->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

</bean>

<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >

</bean>

<!-- SqlSessionFactory -->

<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

  <property name="configLocation"   value="classpath:com/database/config/sql-map-config.xml"/>

  <property name="dataSource" ref="dataSource"/>

</bean>

<bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

  <property name="configLocation"   value="classpath:com/database/config/sql-map-config2.xml"/>

  <property name="dataSource" ref="dataSource2"/>

</bean>

<bean id="SqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">

  <property name="sqlMapClient" ref="sqlMapClient"/>

</bean>

<bean id="SqlMapClientTemplate2" class="org.springframework.orm.ibatis.SqlMapClientTemplate">

<property name="sqlMapClient" ref="sqlMapClient2"/>

</bean>

 

## Transaction 처리

1) 각 datasource별로 transaction 처리

<tx:annotation-driven />

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource"/>

</bean>

<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource2"/>

</bean>

<tx:annotation-driven transaction-manager="txManager"/>

 

2) 접속되는 DB에 혼합 Transaction이 필요한 경우 WAS의 JTA를 이용할 수 있다.

- weblogic

org.springframework.transaction.jta.WebLogicJtaTransactionManager

- jeus

org.springframework.transaction.jta.JtaTransactionManager

- 미지원 WAS

JOTM(Java Open Transaction Manager) 이용

org.springframework.transaction.jta.JotmFactoryBean

 

## DB 별 사용

sqlMapClientTemplate.insert("carcurget.query10", domain);

sqlMapClientTemplate2.insert("carcurget.query10", domain);

 

 

 

2. org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource 를 이용한다.

<!-- dataSource -->

<bean id="ds1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

</bean>

<bean id="ds2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >

</bean>

<!-- dynamicDataSource -->

<bean id="dataSource" class="DynamicDataSource">

<property name="defaultTargetDataSource" ref="ds1" />

<property name="targetDataSources">

<map key-type="DatasourceType">

<entry key="dataSource1" value-ref="ds1" />

<entry key="dataSource2" value-ref="ds2" />

</map>

</property>

</bean>

 

// DynamicDataSource.java

import DatabaseContextHolder;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {

protected Object determineCurrentLookupKey() {

return DatabaseContextHolder.getDatasourceType();

}

}

 

// DatabaseContextHolder.java

import DatasourceType;

public class DatabaseContextHolder {

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

 

public static void setDatasourceType(DatasourceType dbType) {

contextHolder.set(dbType);

}

 

public static DatasourceType getDatasourceType() {

return ((DatasourceType) contextHolder.get());

}

 

public static void clearDatasourceType() {

contextHolder.remove();

}

}

 

// DatasourceType.java

public enum DatasourceType {

dataSource1, dataSource2;

}

 

// DataSource.java

import DatasourceType;

import java.lang.annotation.Annotation;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Target({ java.lang.annotation.ElementType.METHOD })

@Retention(RetentionPolicy.RUNTIME)

public @interface DataSource {

public abstract DatasourceType value();

}

 

## Transaction 처리

1) dataSource에 대해서 DataSourceTransactionManager bean을 설정해 준다.

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" order="2"/>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

</bean>

 

2) java단 method에 annotation으로 처리 가능

@DataSource(DatasourceType.dataSource2)

@Transactional(propagation=Propagation.REQUIRES_NEW)

 

## DB 별 사용

DatabaseContextHolder.setDatasourceType(DatasourceType.dataSource2);