J2EE之巅

 

Spring多数据源解决方案

 

在很多大型应用中都会对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性。而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时的请求及系统状态来动态的决定将数据存储在哪个数据库实例中,以及从哪个数据库提取数据。

Figure 1 数据分割及多数据库架构

通常这种多数据源的逻辑会渗透到业务逻辑中,同时也会给我们使用的数据访问API诸如HibernateiBatis等带来不便(需要指定多个SessionFactorySqlMapClient实例来对应多个DataSource)。


Figure 2 多数据源的选择逻辑渗透至客户端

解决方案


Figure 3 采用Proxy模式来封装数据源选择逻辑

通过采用Proxy模式我们在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。

Client提供选择所需的上下文(因为这是Client所知道的),由虚拟的DataSource根据Client提供的上下文来实现数据源的选择。

Spring2.x的版本中提供了实现这种方式的基本框架,虚拟的DataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数据源的选择逻辑。

实例:

publicclass DynamicDataSource extends AbstractRoutingDataSource {

      static Logger log = Logger.getLogger("DynamicDataSource");

      @Override

      protected Object determineCurrentLookupKey() {

            String userId=(String)DbContextHolder.getContext();

            Integer dataSourceId=getDataSourceIdByUserId(userId);      

            return dataSourceId;

      }

}

实例中通过UserId来决定数据存放在哪个数据库中。

配置文件示例:

<bean id="dataSource" class="com.bitfone.smartdm.datasource.DynamicDataSource"> 

              <property name="targetDataSources"> 

                 <map key-type="java.lang.Integer"> 

                    <entry key="0" value-ref="dataSource0"/>

                    <entry key="1" value-ref="dataSource1"/>

                    <entry key="2" value-ref="dataSource2"/> 

                 </map> 

              </property> 

              <property name="defaultTargetDataSource" ref="dataSource0"/> 

            </bean>

            <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">

                <property name="configLocation" value="classpath:com/bitfone/smartdm/dao/sqlmap/sql-map-config.xml"/>

                <property name="dataSource" ref="dataSource"/>

           </bean>

            <bean id="UserInfoDAO" class="com.bitfone.smartdm.dao.impl.UserInfoDAO">

                 

                  <property name="sqlMapClient" ref="sqlMapClient"/>

            </bean>

蔡超
HP 软件架构师
软件架构顾问
SCEA
IBM Certified Solution Designer for OOA&D vUML2
Chaocai2001@yahoo.com.cn

posted on 2009-07-05 21:53 超越巅峰 阅读(5143) 评论(10)  编辑  收藏

评论

# re: Spring多数据源解决方案[未登录] 2009-07-05 22:36 summer

可以试试这个http://amoeba.meidusa.com/wordpress/  回复  更多评论   

# re: Spring多数据源解决方案 2009-07-05 23:30 凡客诚品

看得不太明白!!  回复  更多评论   

# re: Spring多数据源解决方案 2009-07-05 23:53 subtitle

不错  回复  更多评论   

# re: Spring多数据源解决方案 2009-07-06 01:12 MyYate

AbstractRoutingDataSource对于多数据源访问可以使用,但是如果需要对多数据源进行update操作,还是要借助于jta来控制,lz有其他方法否?  回复  更多评论   

# re: Spring多数据源解决方案 2009-07-06 10:16 awed

看得不太明白,这样对单用户储存是解决问题了,但是如果要对数据的统计和管理呢?又如何处理,总不至于把存在所有数据库里的数据全取出来再分页做吧,还有一些情况,像对于同一用户,可能是需要搞作两个数据源,这种情况又如何对待?  回复  更多评论   

# re: Spring多数据源解决方案 2009-07-06 10:53 99读书人

不错
1  回复  更多评论   

# re: Spring多数据源解决方案 2009-07-22 13:02 Hibernate方言怎么解决

Hibernate方言怎么办  回复  更多评论   

# re: Spring多数据源解决方案[未登录] 2009-10-23 16:47 bs

转载 还打上自己名字..........历害  回复  更多评论   

# re: Spring多数据源解决方案 2009-10-23 17:43 超越巅峰

@bs
你看错了吧,兄弟,这是我的文章,是别人转载我的  回复  更多评论   

# re: Spring多数据源解决方案 2012-12-27 15:21 时磊

请问兄弟,线程安全吗?我按你的思路弄出来了,但是担心线程安全的问题,怎么验证?  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(12)

随笔分类(54)

随笔档案(59)

文章分类(2)

文章档案(1)

相册

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜