<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-35  評論-33  文章-0  trackbacks-0
         本文的幾個關鍵詞,分布式數據源,數據源的動態尋找,分布式事務JTA實現。
         對于一些較大規模的應用,單個數據源是無法支撐起龐大的用戶量,需要引入多數據源,水平層面進行分庫分表,降低單個DB的負載。接下來,我們程序里里面需 要管理不同數據源之前的程序調用,保證功能是WORK的。另外,跨庫就意味著之前單DB的事務就失效了,所以J2EE提出了JTA,分布式的事務管理,往 簡單了說,就是2步提交(two phase),比單步提交更苛刻。實際上他有兩個容器來管理,一個是資源管理器,一個是事務管理。小伙伴們可以發現,這是一個環環相扣的過程。想解決一個 問題,你就得解決這幾個相關的問題。以下代碼,我也是參考了前輩們的思想,進行了改造。

        第一步:XA數據源定義
         選定義一個抽象的父類源,這樣子類可以直接繼承
      
     1  <!-- 兩個數據源的功用配置,方便下面直接引用 -->
     2      <bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init"
     3              destroy-method="close" abstract="true">
     4         <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
     5         <property name="poolSize" value="10" />
     6         <property name="minPoolSize" value="10"/>
     7         <property name="maxPoolSize" value="30"/>
     8         <property name="borrowConnectionTimeout" value="60"/>
     9         <property name="reapTimeout" value="20"/>
    10         <!-- 最大空閑時間 -->
    11         <property name="maxIdleTime" value="60"/>
    12         <property name="maintenanceInterval" value="60" />
    13         <property name="loginTimeout" value="60"/>
    14         <property name="logWriter" value="60"/>
    15         <property name="testQuery">
    16             <value>select 1</value>
    17         </property>
    18         
    19     </bean>
    20 
       A源
         
     1 <!-- 配置第一個數據源 -->
     2     <bean id="dataSource_a" parent="abstractXADataSource">
     3     <!-- value只要兩個數據源不同就行,隨便取名 -->
     4         <property name="uniqueResourceName" value="mysql/sitestone" />
     5         <property name="xaDataSourceClassName"
     6             value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
     7         <property name="xaProperties">
     8             <props>
     9                 <prop key="URL">${jdbc.url.spider}</prop>
    10                 <prop key="user">${jdbc.username}</prop>
    11                 <prop key="password">${jdbc.password}</prop>
    12             </props>
    13         </property>
    14     </bean>
       
    B   源

       
     1 <!-- 配置第二個數據源-->
     2     <bean id="dataSource_b" parent="abstractXADataSource">
     3 <!-- value只要兩個數據源不同就行,隨便取名 -->
     4         <property name="uniqueResourceName" value="mysql/sitesttwo" />
     5         <property name="xaDataSourceClassName"
     6             value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
     7         <property name="xaProperties">
     8             <props>
     9                <prop key="URL">${jdbc_tb.url.spider}</prop>
    10                 <prop key="user">${jdbc_tb.username}</prop>
    11                 <prop key="password">${jdbc_tb.password}</prop>
    12             </props>
    13         </property>
    14     </bean>

    基于SPRING的AbstractRoutingDataSource動態數據路由定義
    1   <bean name="dynamicDatasource" class="com.***.spring.datasource.CustomerDatasource">
    2         <property name="targetDataSources">
    3             <map>
    4                 <entry key="ds_1" value-ref="dataSource_a"/>
    5                 <entry key="ds_2" value-ref="dataSource_b"/>
    6             </map>
    7         </property>
    8         <property name="defaultTargetDataSource" ref="dataSource_a"    />
    9     </bean>
    我這里是使用MYBATIS來進行ORM映射,配置如下
     1  <bean id="sqlSessionFactorya" class="org.mybatis.spring.SqlSessionFactoryBean">
     2         <property name="dataSource" ref="dataSource_a"/>
     3          <property name="typeAliasesPackage" value="com.****.spring.dschange.bean" />
     4          <!-- mapper和resultmap配置路徑 --> 
     5         <property name="mapperLocations">
     6             <list>
     7                 <!-- 表示在com.**目錄下的任意包下的resultmap包目錄中,以-resultmap.xml或-mapper.xml結尾所有文件 --> 
     8                 <value>classpath:com/***/spring/dschange/mapper/ShopMapper.xml</value>
     9             </list>
    10         </property>
    11     </bean>
    12     <bean id="sqlSessionFactoryb" class="org.mybatis.spring.SqlSessionFactoryBean">
    13         <property name="dataSource" ref="dataSource_b"/>
    14          <property name="typeAliasesPackage" value="com.****.spring.dschange.bean" />
    15           <!-- mapper和resultmap配置路徑 --> 
    16         <property name="mapperLocations">
    17             <list>
    18                 <!-- 表示在com.***目錄下的任意包下的resultmap包目錄中,以-resultmap.xml或-mapper.xml結尾所有文件 --> 
    19                 <value>classpath:com/***/spring/dschange/mapper/ShopMapper.xml</value>
    20             </list>
    21         </property>
    22     </bean>
    接下來,一個比較關鍵的地方是對MYBATIS的CustomSqlSessionTemplate的重寫,主要是引入動態數據源sqlSessionFactory。針對不同的數據庫,調用其對應的會話工廠,這對JTA是否啟用,比較重要。
     1  @Override
     2     public SqlSessionFactory getSqlSessionFactory() {
     3  
     4         SqlSessionFactory targetSqlSessionFactory = targetSqlSessionFactorys.get(DataSourceKeyHolder.getDataSourceKey());
     5         if (targetSqlSessionFactory != null) {
     6             return targetSqlSessionFactory;
     7         } else if (defaultTargetSqlSessionFactory != null) {
     8             return defaultTargetSqlSessionFactory;
     9         } else {
    10             Assert.notNull(targetSqlSessionFactorys, "Property 'targetSqlSessionFactorys' or 'defaultTargetSqlSessionFactory' are required");
    11             Assert.notNull(defaultTargetSqlSessionFactory, "Property 'defaultTargetSqlSessionFactory' or 'targetSqlSessionFactorys' are required");
    12         }
    13         return this.sqlSessionFactory;
    14     }
    XML配置
     1  <!-- 配置自定義的SqlSessionTemplate模板,注入相關配置 -->
     2     <bean id="sqlSessionTemplate" class="com.amos.spring.mybatis.CustomSqlSessionTemplate" scope="prototype">
     3         <constructor-arg ref="sqlSessionFactorya" />
     4         <property name="targetSqlSessionFactorys">
     5             <map>     
     6                 <entry value-ref="sqlSessionFactorya" key="ds_1"/>
     7                 <entry value-ref="sqlSessionFactoryb" key="ds_2"/>
     8             </map> 
     9         </property>
    10     </bean>

    掃描配置
    1  <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
     1     <!-- jta -->
     2     <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
     3         init-method="init" destroy-method="close">
     4         <property name="forceShutdown">
     5             <value>true</value>
     6         </property>
     7     </bean>
     8  
     9     <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
    10         <property name="transactionTimeout" value="300" />
    11     </bean>
    12  
    13     <bean id="springTransactionManager"
    14         class="org.springframework.transaction.jta.JtaTransactionManager">
    15         <property name="transactionManager">
    16             <ref bean="atomikosTransactionManager" />
    17         </property>
    18         <property name="userTransaction">
    19             <ref bean="atomikosUserTransaction" />
    20         </property>
    21     </bean>
    22  <tx:annotation-driven transaction-manager="springTransactionManager" proxy-target-class="true" />
    2         <property name="basePackage" value="com.****.spring.dschange.mapper" />
    3         <property name="sqlSessionTemplateBeanName" value="sqlSessionTemplate"/>
    4         <property name="markerInterface" value="com.*****.spring.dschange.mapper.SqlMapper"/>
    5     </bean>

    最后就是JTA的實現配置
     1     <!-- jta -->
     2     <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
     3         init-method="init" destroy-method="close">
     4         <property name="forceShutdown">
     5             <value>true</value>
     6         </property>
     7     </bean>
     8  
     9     <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
    10         <property name="transactionTimeout" value="300" />
    11     </bean>
    12  
    13     <bean id="springTransactionManager"
    14         class="org.springframework.transaction.jta.JtaTransactionManager">
    15         <property name="transactionManager">
    16             <ref bean="atomikosTransactionManager" />
    17         </property>
    18         <property name="userTransaction">
    19             <ref bean="atomikosUserTransaction" />
    20         </property>
    21     </bean>
    22  <tx:annotation-driven transaction-manager="springTransactionManager" proxy-target-class="true" />
    以上,XML配置相關的東西已經完成。
    具體的代碼,請點擊GITHUB查看https://github.com/igool/spring-jta-mybatis


    我的微信公眾號,歡迎溝通學習。
    posted on 2015-09-24 14:29 alexcai 閱讀(7104) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 破了亲妺妺的处免费视频国产| 添bbb免费观看高清视频| 两个人日本WWW免费版| 大学生高清一级毛片免费| 国产成人精品亚洲2020| 亚洲免费电影网站| 亚洲美女色在线欧洲美女| 99精品视频在线免费观看| 亚洲三级电影网址| 四虎精品视频在线永久免费观看 | 国产一区二区三区免费在线观看 | 色欲A∨无码蜜臀AV免费播| 日产亚洲一区二区三区| 黄色网址免费观看| 亚洲日韩精品无码专区| 又黄又大又爽免费视频| 一个人看的www免费高清| 亚洲国产精品无码久久久秋霞2| 无码人妻久久一区二区三区免费 | 亚洲毛片免费视频| 成人免费看黄20分钟| 日韩精品亚洲专区在线影视| 国外亚洲成AV人片在线观看| 久久中文字幕免费视频| 亚洲一区中文字幕| 亚洲另类少妇17p| 在线观看肉片AV网站免费| 亚洲冬月枫中文字幕在线看| 国产精品美女自在线观看免费| xxxxxx日本处大片免费看| 亚洲资源在线观看| 国产成人综合久久精品免费| a级成人毛片免费图片| 亚洲免费人成视频观看| 亚洲第一区精品日韩在线播放| 免费av片在线观看网站| 亚洲乱亚洲乱妇24p| 亚洲午夜福利AV一区二区无码| 永久免费av无码网站韩国毛片| 欧洲乱码伦视频免费国产 | 亚洲综合免费视频|