代理数据库不切换

时间:2015-01-18 11:05:19

标签: spring spring-batch

  • Spring framework 4.1.4
  • Spring batch 3.0.2
  • Tomcat 7

上午,

我已成功使用基于Marten Deinum's Post的配置 动态连接(或创建和连接)仅在运行时已知的dbs。

我遇到的问题是现在间歇性地无法在dbs之间切换。第一个始终有效,但是输入日志代码显示第一个正确创建,然后第二个或第三个未在dataSource == null中触发MdyDataSourceFactory部分 - 如果进程认为它是相同的db,则会出现不会改变,但在某些时候它会触发并连接到后续的数据库!

在dbs之间运行一个简单的JUnit测试切换工作正常(代码正确触发,dbs切换和select语句按预期返回不同的id结果)。

在批处理作业步骤tasklet中调用它。该进程获取resultSets(摘要表)的计数并连接到db。对于每个resultSet,它调用db注册表并且如果存在 - 返回现有的或创建一个新的并返回。

我的动态db xml是:

<bean id="mdyDSRegistry" class="com.k12knowledge.db.MdyDataSourceFactory" />

<bean id="mdyDSTargetSource" class="com.k12knowledge.db.ContextSwappableMdyTargetSource">
    <constructor-arg type="java.lang.Class">
        <value>javax.sql.DataSource</value>
    </constructor-arg>
    <property name="targetRegistry" ref="mdyDSRegistry"></property>
</bean>

<bean id="proxyMdyDataSource" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="proxyInterfaces">
        <list>
            <value>javax.sql.DataSource</value>
        </list>
    </property>
    <property name="targetSource">
        <ref bean="mdyDSTargetSource" />
    </property>
</bean>

MdyDataSourceFactory是:

public class MdyDataSourceFactory implements TargetRegistry {

private ConcurrentMap<String, DataSource> map = new ConcurrentHashMap<String, DataSource>();

@Override
public DataSource getTarget(String context) {
    IClientDs client = MdyContextHolder.getClientDs();

    Assert.notNull(client, "Client was not set.");
    String key = client.getUrl();
    DataSource dataSource = map.get(key);

    if (dataSource == null) {
        System.out.println("dataSource == null - creating new");
        dataSource = getDataSource(client);
        dataSource = map.putIfAbsent(key, dataSource);
        if (dataSource == null) {
            // put success
            dataSource = map.get(key);
        }
    }
    System.out.println("client key: " + key);
    return dataSource;
}

private DataSource getDataSource(IClientDs client) {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(client.getDriver());
    dataSource.setUrl(client.getUrl());
    dataSource.setUsername(client.getUsername());
    dataSource.setPassword(client.getPassword());
    dataSource.setValidationQuery("/* ping */");
    dataSource.setMaxActive(10);
    dataSource.setMaxIdle(5);
    dataSource.setTestOnBorrow(true);
    dataSource.setTestWhileIdle(true);
    dataSource.setRemoveAbandoned(true);
    dataSource.setRemoveAbandonedTimeout(20);
    dataSource.setTimeBetweenEvictionRunsMillis(34000);
    dataSource.setMinEvictableIdleTimeMillis(55000);
    try {
        System.out.println("dataSource " + client.getUrl() + " closed ? " + dataSource.getConnection().isClosed());
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return dataSource;
}

}

有一次我认为我使用的密钥存在问题(某些数据库的名称只有1个字母不同)。然后我尝试在密钥的前面添加一个UUID,看看是不是问题 - 没有变化。

真的很困惑为什么它不起作用......任何指针都非常感激。

感谢您的关注。

ContextHolder

public abstract class ContextHolder {
private static final ThreadLocal<IClientDs> holder = new ThreadLocal<IClientDs>();

public static void setClientDs(IClientDs context) {
    LoggerFactory.getLogger(ContextHolder.class).debug("context set '{}'", context);
    holder.set(context);
}

public static IClientDs getClientDs() {
    return (IClientDs) holder.get();
}

}

0 个答案:

没有答案