我有一个使用Oracle DB作为后端数据源的Web应用程序。这个Oracle数据库实例每天都在刷新,当它被刷新时,我们必须无缝切换到另一个数据库(原始数据库的副本),而另一个数据库(副本)正在刷新,它应该回退到原始的Oracle数据库。
我们正在使用Spring JDBC。
实现这一目标的最佳方法是什么?
答案 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(....);
}