J2EE之巔

           

          Spring多數(shù)據(jù)源解決方案

           

          在很多大型應(yīng)用中都會(huì)對(duì)數(shù)據(jù)進(jìn)行切分,并且采用多個(gè)數(shù)據(jù)庫(kù)實(shí)例進(jìn)行管理,這樣可以有效提高系統(tǒng)的水平伸縮性。而這樣的方案就會(huì)不同于常見的單一數(shù)據(jù)實(shí)例的方案,這就要程序在運(yùn)行時(shí)根據(jù)當(dāng)時(shí)的請(qǐng)求及系統(tǒng)狀態(tài)來(lái)動(dòng)態(tài)的決定將數(shù)據(jù)存儲(chǔ)在哪個(gè)數(shù)據(jù)庫(kù)實(shí)例中,以及從哪個(gè)數(shù)據(jù)庫(kù)提取數(shù)據(jù)。

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

          通常這種多數(shù)據(jù)源的邏輯會(huì)滲透到業(yè)務(wù)邏輯中,同時(shí)也會(huì)給我們使用的數(shù)據(jù)訪問(wèn)API諸如HibernateiBatis等帶來(lái)不便(需要指定多個(gè)SessionFactorySqlMapClient實(shí)例來(lái)對(duì)應(yīng)多個(gè)DataSource)。


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

          解決方案


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

          通過(guò)采用Proxy模式我們?cè)诜桨钢袑?shí)現(xiàn)一個(gè)虛擬的數(shù)據(jù)源,并且用它來(lái)封裝數(shù)據(jù)源選擇邏輯,這樣就可以有效地將數(shù)據(jù)源選擇邏輯從Client中分離出來(lái)。

          Client提供選擇所需的上下文(因?yàn)檫@是Client所知道的),由虛擬的DataSource根據(jù)Client提供的上下文來(lái)實(shí)現(xiàn)數(shù)據(jù)源的選擇。

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

          實(shí)例:

          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;

                }

          }

          實(shí)例中通過(guò)UserId來(lái)決定數(shù)據(jù)存放在哪個(gè)數(shù)據(jù)庫(kù)中。

          配置文件示例:

          <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 軟件架構(gòu)師
          軟件架構(gòu)顧問(wèn)
          SCEA
          IBM Certified Solution Designer for OOA&D vUML2
          Chaocai2001@yahoo.com.cn

          posted on 2009-07-05 21:53 超越巔峰 閱讀(5152) 評(píng)論(10)  編輯  收藏

          評(píng)論

          # re: Spring多數(shù)據(jù)源解決方案[未登錄](méi) 2009-07-05 22:36 summer

          可以試試這個(gè)http://amoeba.meidusa.com/wordpress/  回復(fù)  更多評(píng)論   

          # re: Spring多數(shù)據(jù)源解決方案 2009-07-05 23:30 凡客誠(chéng)品

          看得不太明白!!  回復(fù)  更多評(píng)論   

          # re: Spring多數(shù)據(jù)源解決方案 2009-07-05 23:53 subtitle

          不錯(cuò)  回復(fù)  更多評(píng)論   

          # re: Spring多數(shù)據(jù)源解決方案 2009-07-06 01:12 MyYate

          AbstractRoutingDataSource對(duì)于多數(shù)據(jù)源訪問(wèn)可以使用,但是如果需要對(duì)多數(shù)據(jù)源進(jìn)行update操作,還是要借助于jta來(lái)控制,lz有其他方法否?  回復(fù)  更多評(píng)論   

          # re: Spring多數(shù)據(jù)源解決方案 2009-07-06 10:16 awed

          看得不太明白,這樣對(duì)單用戶儲(chǔ)存是解決問(wèn)題了,但是如果要對(duì)數(shù)據(jù)的統(tǒng)計(jì)和管理呢?又如何處理,總不至于把存在所有數(shù)據(jù)庫(kù)里的數(shù)據(jù)全取出來(lái)再分頁(yè)做吧,還有一些情況,像對(duì)于同一用戶,可能是需要搞作兩個(gè)數(shù)據(jù)源,這種情況又如何對(duì)待?  回復(fù)  更多評(píng)論   

          # re: Spring多數(shù)據(jù)源解決方案 2009-07-06 10:53 99讀書人

          不錯(cuò)
          1  回復(fù)  更多評(píng)論   

          # re: Spring多數(shù)據(jù)源解決方案 2009-07-22 13:02 Hibernate方言怎么解決

          Hibernate方言怎么辦  回復(fù)  更多評(píng)論   

          # re: Spring多數(shù)據(jù)源解決方案[未登錄](méi) 2009-10-23 16:47 bs

          轉(zhuǎn)載 還打上自己名字..........歷害  回復(fù)  更多評(píng)論   

          # re: Spring多數(shù)據(jù)源解決方案 2009-10-23 17:43 超越巔峰

          @bs
          你看錯(cuò)了吧,兄弟,這是我的文章,是別人轉(zhuǎn)載我的  回復(fù)  更多評(píng)論   

          # re: Spring多數(shù)據(jù)源解決方案 2012-12-27 15:21 時(shí)磊

          請(qǐng)問(wèn)兄弟,線程安全嗎?我按你的思路弄出來(lái)了,但是擔(dān)心線程安全的問(wèn)題,怎么驗(yàn)證?  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(12)

          隨筆分類(54)

          隨筆檔案(59)

          文章分類(2)

          文章檔案(1)

          相冊(cè)

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 万全县| 故城县| 庄河市| 喜德县| 从江县| 靖安县| 赞皇县| 太康县| 徐汇区| 屏南县| 秭归县| 伽师县| 潢川县| 琼海市| 镇巴县| 安塞县| 马边| 宜川县| 囊谦县| 日土县| 蓝山县| 陆丰市| 嫩江县| 涿鹿县| 泸西县| 汉寿县| 新闻| 那坡县| 安庆市| 永仁县| 永新县| 威信县| 伊金霍洛旗| 沧源| 普定县| 双江| 壶关县| 兰西县| 南召县| 信宜市| 景泰县|