0

在我的 spring mvc 应用程序中,我需要根据用户在前端选择的功能在给定时间连接到多个数据库。让我们说 :

1.我有 3 种不同的环境(PROD、PRE-PROD 和 Staging 等等……)

2.用户想查看给定数据库中的表列表。用户将从选择框中选择项目并提交。根据用户选择,它需要连接到相应的数据库并获取结果。

3.有时某些数据库可能会出现故障,如果我为每个数据库创建 JNDI 数据源并将它们映射到 jdbcTemplate 并且所有这些 jdbcTemplaates 都被定义为我的 DAO 中的属性,例如

<bean id="prodDataSource" ref="prodDSPool"/>
<bean id="preProdDataSource" ref="preProdDSPool"/>
<bean id="statgingDataSource" ref="stagingDSPool" />
...
...

我还有另一个 bean,它不过是我的 DAO

<bean id="myConnectionsDAO" class="com.example.MyConnectionsDAOImpl">
       <property name="prodDataSource">
             <ref bean="prodDataSource"/>
       </property>
       <property name="preProdDataSource">
             <ref bean="preProdDataSource"/>
       </property>
       <property name="preProdDataSource">
             <ref bean="preProdDataSource"/>
       </property>
</bean>

MyConnectionDAO 是一个具有上述属性的 getter 和 setter 的 pojo。

正如我上面所说,取决于用户选择,我的服务类获取关联的数据源并构建 jdbcTemplate 并查询数据库,如

if(env.equalsIgnoreCase(EnvEnum.PROD.toString())
{
  JdbcTemplate prodTemplate = new JdbcTemplate(myConnectionsDAO.getProdDataSource());
prodTemplate.queryForList("select name form sysibm.systables where creator='admin');
//Core business logic to analyze those tables and proceed... 
}else if {//preprod logic} else if{//staging logic}

而且我有很多复杂的功能可以处理来自 DB2 数据库的数据。由于我正在使用spring config将数据源注入到我的dao中;出于任何原因,如果一个数据库/数据源已关闭,我将无法使用我的应用程序并获取空指针,因为一个或多个数据源已关闭。

我该如何处理这些错误?基本上,如果至少有一个 ds 启动,我希望我的应用程序启动并运行。我使用上述配置配置了大约 50 个数据库。

我很困惑,不知道如何解决这个问题。提前谢谢各位...

4

1 回答 1

0

基本上,您需要为每个数据库管理自己的 Spring Application Context。

也就是说,您将启动一个应用程序上下文作为给定数据库的根应用程序上下文的子项。然后,您将不得不管理动态数据库/数据源应用程序上下文的生命周期。

另一种选择是编写一个自定义的单一数据源,在幕后自动执行此路由。根据您的编辑,哪个看起来是最好的选择。

public class RoutingDatasource implements DataSource, ApplicationContextAware {

    private volatile DataSource realDataSource;
    private ApplicationContext ac;

    // You must do some thread locking here that will be rather complicated.
    // That is not included in this example
    public void switchDatasource(String name) {
        this.realDataSource = this.ac.getBean(name, DataSource.class);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ac = applicationContext;
    }

    // delegate to realDataSource


}

您将需要弄清楚如何安全地锁定数据源对象。我会把它留给你(抱歉没时间了)。

于 2012-05-17T21:34:07.153 回答