简体   繁体   中英

Not routing DataSource with Spring 3 and MyBatis

I have a default database and sometimes I have to make a select in another database.

I've searched many blogs and questions here about this, but couldn't make it work.

Tried the http://blog.springsource.org/2007/01/23/dynamic-datasource-routing/ way. Nothing.

Code for RouterDataSource class:

public class RouterDataSource extends AbstractRoutingDataSource {   
    @Override
    protected DataSourceEnum determineCurrentLookupKey() {
         return DataSourceContextHolder.getTargetDataSource();
    }   
}

Code for DataSourceContextHolder class:

public class DataSourceContextHolder {
     private static final ThreadLocal<DataSourceEnum> contextHolder = new ThreadLocal<DataSourceEnum>();

     public static void setTargetDataSource(DataSourceEnum targetDataSource) {
         Assert.notNull(targetDataSource, "Target data source cannot be null");
         contextHolder.set(targetDataSource);
     }

     public static DataSourceEnum getTargetDataSource() {
         if (contextHolder.get() != null)
             return (DataSourceEnum) contextHolder.get();
         else
             return DataSourceEnum.DB1;
     }

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

Code for the method calling to change the database:

@Override
public CodeHD getCategoryByCode(String code) throws BusinessException {
    DataSourceContextHolder.setTargetDataSource(DataSourceEnum.DATABASE2);
    return (CodeHD) persistency.getObject(GETOBJECT_BY_CODE, code);
}

Code for DatasourceEnum class:

public enum DataSourceEnum {
    DB1,
    DB2;
}

And finally the configuration on my applicationContext.xml:

<bean id="parentDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" abstract="true">
    <property name="driverClass" value="oracle.jdbc.pool.OracleDataSource" />
    <property name="acquireIncrement" value="10" />
    <property name="idleConnectionTestPeriod" value="60" />
    <property name="maxStatements" value="50" />
    <property name="minPoolSize" value="5" />
    <property name="maxPoolSize" value="15" />
</bean>

<bean id="database1DS" parent="parentDataSource">
    <property name="jdbcUrl" value="jdbc:oracle:thin:@database1:1521:xe" />
    <property name="user" value="user" />
    <property name="password" value="password" />
</bean>

<bean id="database2DS" parent="parentDataSource">
    <property name="jdbcUrl" value="jdbc:oracle:thin:@database2:1521:xe" />
    <property name="user" value="user" />
    <property name="password" value="password" />
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     <property name="dataSource" ref="dataSource"/>
  </bean>

<bean id="dataSource" class="package.RouterDataSource">
    <property name="defaultTargetDataSource" ref="database1DS"/>
    <property name="targetDataSources">
        <map key-type="package.DataSourceEnum">
            <entry key="DB1" value-ref="database1DS"/>
            <entry key="DB2" value-ref="database2DS"/>
        </map>
    </property>
</bean>

The problem is that when I set it to DB2 it won't change.

Can anyone help me?

尝试将两个静态方法都设为非静态方法,并在上下文持有者通过的情况下传递R引用。

First make sure that database2DS is working correctly. Make the defaultTargetDatasource database2DS and verify that it is not using DB1 still and there are no other errors using database2DS as the default. If the AbstractRoutingDataSource fails to resolve a DataSource in the targetDataSources you cannot switch to it.

AbstractRoutingDataSource will only change the DataSource when getConnection is called. Whatever persistence framework you're using is probably caching the Connection and not calling getConnection in between persistency.getObject(). However you are getting your persistency object, try getting a new persistency object after you change the datasource in DataSourceContextHolder. If this solves your problem, try creating a class that maintains your persistency object and handles changing the datasource. That way when you change the datasource you can modify your persistency manager object in one spot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM