Spring中的双DB连接?

时间:2016-11-23 02:06:01

标签: java spring spring-jdbc

我有一个使用Oracle DB作为后端数据源的Web应用程序。这个Oracle数据库实例每天都在刷新,当它被刷新时,我们必须无缝切换到另一个数据库(原始数据库的副本),而另一个数据库(副本)正在刷新,它应该回退到原始的Oracle数据库。

我们正在使用Spring JDBC。

实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

这在很大程度上取决于您的要求。我会使用Dev-ops。你想要得到的Dev-ops取决于你。每次我看到一个问题时都会发表评论,例如在Spring中切换数据库,或者重新构建一个单独的bean等等。开发人员总是做一些非常奇怪的事情,通常是因为他们认为他们有一定的要求,但是他们不会这样做。真的。

有Dev-ops工具可以拥有数据库的只读克隆,可以从任何你想要的频率从其他来源更新。发生这种情况时,无需切换到另一个数据库。 (另请查看数据库中有许多只读克隆的模式,以及一个真正的数据库,其中所有写入都被重定向到)

即使这不符合您的要求,您也可以使用Dev-ops可视化端口和数据库URL等,并随时随地重定向。我也会杀掉这次跳跃之间的所有会话,但那只是我。

使用Dev-ops可以将这类内容保留在Spring Web应用程序的代码中,使其保持干净,代码不需要随着需求的变化而变化。对于一个将这些东西硬编码到其中的项目,这将是令人讨厌的,我建议你谨慎地考虑你将采取什么样的道路。如果你确实关闭了Dev-ops,那么你就不会遇到这些问题。

答案 1 :(得分:0)

由于管理层未同意DevOps相关解决方案,因此我必须继续执行 AbstractRoutingDataSource

解决方案很简单,您只需扩展AbstractRoutingDataSource并通过覆盖 determineCurrentLookupKey() 方法提供路由条件。

您的自定义数据源将如下所示

public class ResourceAwareMyDataSource extends AbstractRoutingDataSource {

    private static final Logger logger = LoggerFactory.getLogger(ResourceAwareMyDataSource.class);

    @Override
    protected Object determineCurrentLookupKey() {

        try {
            //Check whether the primary DB is active 
            if(primaryIsActive()) {
                return "Primary"
            }
        } catch (Exception e) {
            logger.error("Error occurred when checking  primary",e);
            logger.info("Switching back to Secondary..");
            return "Secondary";
        }
        //Primary is inactive
        logger.info("Primary is Inactive, Switching back to Secondary");
        return "Secondary";
    }
}

这将是您对上述数据源的Java配置

@Bean
@Qualifier("myCustomizedDataSource")
public DataSource resourceAwareMyDataSource() {

    ResourceAwareMyDataSource dataSource = new ResourceAwareMyDataSource ();
    Map<Object, Object> targetDataSourcesMap = new HashedMap();
    targetDataSourcesMap.put("Primary", getPrimaryDataSource());
    targetDataSourcesMap.put("Secondary", getSecondaryDataSource());
    dataSource.setTargetDataSources(targetDataSourcesMap);
    return dataSource;
}

像往常一样,您的主要和辅助数据源将如下所示,这里我提供了两个基本数据源连接到主要和次要

public DataSource getPrimaryDataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(...);
    dataSource.setUrl(...);
    dataSource.setUsername(...);
    dataSource.setPassword(...);
    dataSource.setValidationQuery(...);
    return dataSource;
}

public DataSource getSecondaryDataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(...);
    dataSource.setUrl(...);
    dataSource.setUsername(...);
    dataSource.setPassword(...);
    dataSource.setValidationQuery(....);
}