在Spring MVC中管理多个数据源

时间:2012-05-17 21:23:52

标签: spring spring-mvc datasource config

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

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

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

3.有些时候某些数据库会崩溃,如果我为每个数据库创建JNDI数据源并将它们映射到jdbcTemplate,所有这些jdbcTemplaates都被定义为我的DAO中的属性,如

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

我还有另一个豆子,只不过是我的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配置将数据源注入到我的dao中;由于任何原因,如果一个数据库/数据源关闭,我无法使用我的应用程序并获得nullpointer,因为一个或多个数据源已关闭。

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

我非常困惑,并没有弄清楚如何解决这个问题。 先谢谢你们......

1 个答案:

答案 0 :(得分:0)

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

也就是说,您将为给定数据库启动应用程序上下文作为根application context的子项。然后,您必须管理动态db / datasource应用程序上下文的生命周期。

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

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


}

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