隨筆-199  評論-203  文章-11  trackbacks-0
           在很多大型應(yīng)用中都會對數(shù)據(jù)進行切分,并且采用多個數(shù)據(jù)庫實例進行管理,這樣可以有效提高系統(tǒng)的水平伸縮性。而這樣的方案就會不同于常見的單一數(shù)據(jù)實例的方案,這就要程序在運行時根據(jù)當(dāng)時的請求及系統(tǒng)狀態(tài)來動態(tài)的決定將數(shù)據(jù)存儲在哪個數(shù)據(jù)庫實例中,以及從哪個數(shù)據(jù)庫提取數(shù)據(jù)。

           

          Figure 1 數(shù)據(jù)分割及多數(shù)據(jù)庫架構(gòu)

              通常這種多數(shù)據(jù)源的邏輯會滲透到業(yè)務(wù)邏輯中,同時也會給我們使用的數(shù)據(jù)訪問API諸如Hibernate和iBatis等帶來不便(需要指定多個SessionFactory或SqlMapClient實例來對應(yīng)多個DataSource)。


          Figure 2 多數(shù)據(jù)源的選擇邏輯滲透至客戶端

           

              解決方案


          Figure 3 采用Proxy模式來封裝數(shù)據(jù)源選擇邏輯

              通過采用Proxy模式我們在方案中實現(xiàn)一個虛擬的數(shù)據(jù)源,并且用它來封裝數(shù)據(jù)源選擇邏輯,這樣就可以有效地將數(shù)據(jù)源選擇邏輯從Client中分離出來。

              Client提供選擇所需的上下文(因為這是Client所知道的),由虛擬的DataSource根據(jù)Client提供的上下文來實現(xiàn)數(shù)據(jù)源的選擇。

              Spring2.x的版本中提供了實現(xiàn)這種方式的基本框架,虛擬的DataSource僅需繼承AbstractRoutingDataSource實現(xiàn)determineCurrentLookupKey()在其中封裝數(shù)據(jù)源的選擇邏輯。

              實例:

          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來決定數(shù)據(jù)存放在哪個數(shù)據(jù)庫中。

              配置文件示例:

          <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>

          posted on 2009-07-27 21:54 Werther 閱讀(4815) 評論(6)  編輯  收藏 所屬分類: 10.Java

          評論:
          # re: Spring多數(shù)據(jù)源解決方案 2009-07-28 09:35 | 揚帆出海
          是個不錯的方法,不過有些地方還是不明白。
          以前采用的方式是創(chuàng)建兩個sessionFactory,配置數(shù)據(jù)訪問類的時候選擇相應(yīng)的sessionFactory。

          我有兩個問題:
          1)sql-map-config.xml里是什么內(nèi)容
          2)String userId=(String)DbContextHolder.getContext();上下文中是怎么管理ID的?  回復(fù)  更多評論
            
          # re: Spring多數(shù)據(jù)源解決方案 2009-07-28 13:57 | 海邊沫沫
          不錯,收藏!  回復(fù)  更多評論
            
          # re: Spring多數(shù)據(jù)源解決方案 2009-07-28 22:19 | MyYate
          這個沒法保證事務(wù)啊,我如果要對其中兩個數(shù)據(jù)源進行更新操作,這種就不能實現(xiàn)了吧!  回復(fù)  更多評論
            
          # re: Spring多數(shù)據(jù)源解決方案 2009-07-29 09:13 | 和尚
          不錯,不過應(yīng)該再詳細點就解答上面兩個網(wǎng)友的問題就最好了:一個是如何管理sessionFactory?是spring來管理嗎?底層實現(xiàn)了?另一個就是事務(wù),如何細粒度事務(wù)?  回復(fù)  更多評論
            
          # re: Spring多數(shù)據(jù)源解決方案 2009-07-29 15:44 | lordz
          如果是MySQL+Oracle,sql-map-config.xml是不一樣的 那怎么配置呢?  回復(fù)  更多評論
            
          # re: Spring多數(shù)據(jù)源解決方案 [未登錄] 2009-12-01 13:23 | 懶貓
          如果各個dataSource上的數(shù)據(jù)庫結(jié)構(gòu)不一樣的話,這個方法是不能解決問題的  回復(fù)  更多評論
            
          主站蜘蛛池模板: 桦川县| 苏尼特左旗| 永平县| 普陀区| 温泉县| 河南省| 红原县| 旅游| 肥西县| 岳西县| 凌云县| 贡觉县| 江门市| 商丘市| 璧山县| 云阳县| 五河县| 高阳县| 堆龙德庆县| 望奎县| 读书| 海原县| 长宁县| 泰顺县| 奇台县| 五大连池市| 石景山区| 自贡市| 时尚| 揭东县| 彰化市| 瑞金市| 五华县| 玛沁县| 东辽县| 牡丹江市| 建湖县| 宣恩县| 沅江市| 九寨沟县| 剑河县|