0

我有一个默认数据库,有时我必须在另一个数据库中进行选择。

我在这里搜索了许多关于此的博客和问题,但无法使其发挥作用。

尝试了http://blog.springsource.org/2007/01/23/dynamic-datasource-routing/方式。没有什么。

RouterDataSource 类的代码:

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

DataSourceContextHolder 类的代码:

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();
     }
}

调用更改数据库的方法的代码:

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

DatasourceEnum 类的代码:

public enum DataSourceEnum {
    DB1,
    DB2;
}

最后是我的 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>

问题是当我将它设置为 DB2 时它不会改变。

谁能帮我?

4

2 回答 2

0

首先确保 database2DS 工作正常。制作 defaultTargetDatasource database2DS 并验证它是否仍在使用 DB1,并且使用 database2DS 作为默认值没有其他错误。如果 AbstractRoutingDataSource 无法解析 targetDataSources 中的 DataSource,则无法切换到它。

AbstractRoutingDataSource 只会在调用 getConnection 时更改 DataSource。无论您使用什么持久性框架,都可能缓存 Connection 而不是在 persistence.getObject() 之间调用 getConnection。但是,您正在获取持久性对象,请在更改 DataSourceContextHolder 中的数据源后尝试获取新的持久性对象。如果这解决了您的问题,请尝试创建一个类来维护您的持久性对象并处理更改数据源。这样,当您更改数据源时,您可以在一处修改您的持久性管理器对象。

于 2012-10-24T20:15:45.487 回答
0

如果上下文持有者,请尝试将两个静态方法都设为非静态并传递 R 引用。

于 2012-10-24T18:53:47.713 回答