Spring分布式事务在service中动态切换数据源

Spring分布式事务在service中动态切换数据源

项目采用的是struts2+spring+ibatis架构,下面是关键部分代码:

applicationContext.xml:

  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2. <beans xmlns=“http://www.springframework.org/schema/beans”  
  3.        xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”  
  4.        xmlns:context=“http://www.springframework.org/schema/context”  
  5.        xmlns:aop=“http://www.springframework.org/schema/aop”  
  6.        xmlns:tx=“http://www.springframework.org/schema/tx”  
  7.        xsi:schemaLocation=”http://www.springframework.org/schema/beans  
  8.            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  9.            http://www.springframework.org/schema/context  
  10.            http://www.springframework.org/schema/context/spring-context-2.5.xsd  
  11.            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  12.            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd”   
  13.            default-autowire=“byName” default-lazy-init=“false”>  
  14.       
  15.     <context:component-scan base-package=“com.ssi.*” />  
  16.     <!– 属性文件读入 –>  
  17.     <bean id=“propertyConfigurer” class=“org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”>  
  18.         <property name=“locations”>  
  19.             <list>  
  20.                 <value>classpath*:jdbc.properties</value>  
  21.             </list>  
  22.         </property>  
  23.     </bean>  
  24.       
  25.       
  26.     <!– 配置sqlMapclient –>  
  27.     <bean id=“sqlMapClient” class=“org.springframework.orm.ibatis.SqlMapClientFactoryBean”>  
  28.         <property name=“configLocation” value=“classpath:ibatis-sqlmap-config.xml” />  
  29.         <property name=“dataSource” ref=“dataSource” />  
  30.     </bean>  
  31.       
  32.     <bean id=“sqlMapClient1” class=“org.springframework.orm.ibatis.SqlMapClientFactoryBean”>  
  33.         <property name=“configLocation” value=“classpath:ibatis-sqlmap-config.xml” />  
  34.         <property name=“dataSource” ref=“db1” />  
  35.     </bean>  
  36.     <bean id=“sqlMapClient2” class=“org.springframework.orm.ibatis.SqlMapClientFactoryBean”>  
  37.         <property name=“configLocation” value=“classpath:ibatis-sqlmap-config.xml” />  
  38.         <property name=“dataSource” ref=“db2” />  
  39.     </bean>  
  40.     <bean id=“sqlMapClientCenter” class=“org.springframework.orm.ibatis.SqlMapClientFactoryBean”>  
  41.         <property name=“configLocation” value=“classpath:ibatis-sqlmap-config.xml” />  
  42.         <property name=“dataSource” ref=“center” />  
  43.     </bean>  
  44.       
  45.     <bean id=“dynamicSqlMapClientDaoSupport” class=“com.ssi.dao.DynamicSqlClientDaoSupport”>    
  46.         <property name=“targetSqlMapClients”>    
  47.             <map>    
  48.                 <entry key=“db1” value-ref=“sqlMapClient1” />    
  49.                 <entry key=“db2” value-ref=“sqlMapClient2” />    
  50.                 <entry key=“center” value-ref=“sqlMapClientCenter” />    
  51.             </map>    
  52.         </property>    
  53.         <property name=“defaultSqlMapClient” ref=“sqlMapClientCenter” />    
  54.     </bean>    
  55.     <bean id=“ibatisDaoSupport” class=“com.ssi.dao.IbatisDaoSupport” parent=“dynamicSqlMapClientDaoSupport”></bean>  
  56.       
  57.     <bean id=“userDao” class=“com.ssi.dao.impl.UserDaoImpl” parent=“ibatisDaoSupport”></bean>  
  58.   
  59.     <!– 支持 @AspectJ 标记–>  
  60.     <aop:aspectj-autoproxy proxy-target-class=“true”/>  
  61.   
  62.     <!– 配置JTA的事务管理器 –>     
  63.     <bean id=“atomikosTransactionManager” class=“com.atomikos.icatch.jta.UserTransactionManager”    init-method=“init” destroy-method=“close”>     
  64.         <property name=“forceShutdown” value=“true” />     
  65.     </bean>     
  66.     <bean id=“atomikosUserTransaction” class=“com.atomikos.icatch.jta.UserTransactionImp”>     
  67.         <property name=“transactionTimeout” value=“300” />     
  68.     </bean>     
  69.     <bean id=“springTransactionManager”  class=“org.springframework.transaction.jta.JtaTransactionManager”>     
  70.         <property name=“transactionManager” ref=“atomikosTransactionManager” />     
  71.         <property name=“userTransaction” ref=“atomikosUserTransaction” />     
  72.     </bean>  
  73.     <!– 配置通知 –>  
  74.     <tx:advice id=“txAdvice” transaction-manager=“springTransactionManager”>  
  75.         <tx:attributes>  
  76.              <tx:method name=“*” rollback-for=“Exception,RuntimeException,com.ssi.exception.SystemException” propagation=“REQUIRED” />  
  77.         </tx:attributes>  
  78.     </tx:advice>  
  79.       
  80.   
  81.       
  82.     <!– 以AspectJ方式 定义 AOP –>   
  83.   
  84.     <aop:config>  
  85.         <aop:advisor pointcut=“execution(* com.ssi.service..*Service*.*(..))” advice-ref=“txAdvice” />  
  86.     </aop:config>  
  87.       
  88.       
  89.     <!– spring 定时器任务开始 –>  
  90.     <bean name=“job” class=“org.springframework.scheduling.quartz.JobDetailBean”>     
  91.          <property name=“jobClass”>     
  92.              <value>com.ssi.action.TimerAction</value>    
  93.          </property>     
  94.          <property name=“jobDataAsMap”>    
  95.              <map>   
  96.                   <!– timeout属性设定了当服务器启动后过10秒钟首次调用你的JobAction –>  
  97.                   <entry key=“timeout”>     
  98.                      <value>10</value>    
  99.                   </entry>    
  100.              </map>     
  101.          </property>     
  102.     </bean>    
  103.     <bean id=“cronTrigger” class=“org.springframework.scheduling.quartz.CronTriggerBean”>     
  104.          <property name=“jobDetail”>     
  105.              <ref bean=“job”/>     
  106.          </property>     
  107.          <property name=“cronExpression”>     
  108.              <value>0 53 15 ? * MON-FRI</value>    
  109.          </property>     
  110.     </bean>     
  111.     <bean class=“org.springframework.scheduling.quartz.SchedulerFactoryBean” autowire=“no”>    
  112.          <property name=“triggers”>     
  113.              <list>     
  114.                  <ref local=“cronTrigger”/>    
  115.              </list>    
  116.          </property>     
  117.     </bean>   
  118.     <!– spring 定时器任务结束 –>  
  119.       
  120. </beans>  
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" 
           default-autowire="byName" default-lazy-init="false">

    <context:component-scan base-package="com.ssi.*" />
    <!-- 属性文件读入 -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath*:jdbc.properties</value>
            </list>
        </property>
    </bean>


    <!-- 配置sqlMapclient -->
    <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation" value="classpath:ibatis-sqlmap-config.xml" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="sqlMapClient1" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation" value="classpath:ibatis-sqlmap-config.xml" />
        <property name="dataSource" ref="db1" />
    </bean>
    <bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation" value="classpath:ibatis-sqlmap-config.xml" />
        <property name="dataSource" ref="db2" />
    </bean>
    <bean id="sqlMapClientCenter" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation" value="classpath:ibatis-sqlmap-config.xml" />
        <property name="dataSource" ref="center" />
    </bean>

    <bean id="dynamicSqlMapClientDaoSupport" class="com.ssi.dao.DynamicSqlClientDaoSupport">  
        <property name="targetSqlMapClients">  
            <map>  
                <entry key="db1" value-ref="sqlMapClient1" />  
                <entry key="db2" value-ref="sqlMapClient2" />  
                <entry key="center" value-ref="sqlMapClientCenter" />  
            </map>  
        </property>  
        <property name="defaultSqlMapClient" ref="sqlMapClientCenter" />  
    </bean>  
    <bean id="ibatisDaoSupport" class="com.ssi.dao.IbatisDaoSupport" parent="dynamicSqlMapClientDaoSupport"></bean>

    <bean id="userDao" class="com.ssi.dao.impl.UserDaoImpl" parent="ibatisDaoSupport"></bean>

    <!-- 支持 @AspectJ 标记-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <!-- 配置JTA的事务管理器 -->   
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"    init-method="init" destroy-method="close">   
        <property name="forceShutdown" value="true" />   
    </bean>   
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">   
        <property name="transactionTimeout" value="300" />   
    </bean>   
    <bean id="springTransactionManager"  class="org.springframework.transaction.jta.JtaTransactionManager">   
        <property name="transactionManager" ref="atomikosTransactionManager" />   
        <property name="userTransaction" ref="atomikosUserTransaction" />   
    </bean>
    <!-- 配置通知 -->
    <tx:advice id="txAdvice" transaction-manager="springTransactionManager">
        <tx:attributes>
             <tx:method name="*" rollback-for="Exception,RuntimeException,com.ssi.exception.SystemException" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>



    <!-- 以AspectJ方式 定义 AOP --> 

    <aop:config>
        <aop:advisor pointcut="execution(* com.ssi.service..*Service*.*(..))" advice-ref="txAdvice" />
    </aop:config>


    <!-- spring 定时器任务开始 -->
    <bean name="job" class="org.springframework.scheduling.quartz.JobDetailBean">   
         <property name="jobClass">   
             <value>com.ssi.action.TimerAction</value>  
         </property>   
         <property name="jobDataAsMap">  
             <map> 
                  <!-- timeout属性设定了当服务器启动后过10秒钟首次调用你的JobAction -->
                  <entry key="timeout">   
                     <value>10</value>  
                  </entry>  
             </map>   
         </property>   
    </bean>  
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">   
         <property name="jobDetail">   
             <ref bean="job"/>   
         </property>   
         <property name="cronExpression">   
             <value>0 53 15 ? * MON-FRI</value>  
         </property>   
    </bean>   
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="no">  
         <property name="triggers">   
             <list>   
                 <ref local="cronTrigger"/>  
             </list>  
         </property>   
    </bean> 
    <!-- spring 定时器任务结束 -->

</beans>


  1.   
applicationContext-datasource.xml

  1. <?xml version=“1.0” encoding=“UTF-8”?>  
  2. <beans xmlns=“http://www.springframework.org/schema/beans”  
  3.     xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”  
  4.     xmlns:aop=“http://www.springframework.org/schema/aop”  
  5.     xmlns:tx=“http://www.springframework.org/schema/tx”  
  6.     xsi:schemaLocation=”  
  7.     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  8.     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
  9.     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd”>  
  10.       
  11.     <!–指定Spring配置中用到的属性文件–>  
  12.     <bean id=“propertyConfig” class=“org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”>  
  13.         <property name=“locations”>  
  14.             <list>  
  15.                 <value>classpath:jdbc.properties</value>  
  16.             </list>  
  17.         </property>  
  18.     </bean>  
  19.     <!– JTA 数据源配置 –>  
  20.     <bean id=“center” class=“com.atomikos.jdbc.AtomikosDataSourceBean” init-method=“init” destroy-method=“close”>  
  21.         <property name=“uniqueResourceName”>  
  22.             <value>mysql/center</value>  
  23.         </property>  
  24.         <property name=“xaDataSourceClassName”>  
  25.             <value>{jta.driver.className}</span><span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"xaProperties"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">props</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"url"</span><span class="tag">&gt;</span><span>{center.jdbc.driver.url}</prop>  
  26.                 <prop key=“user”>{center.sql.user.name}</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"password"</span><span class="tag">&gt;</span><span>{center.sql.user.password}</prop>  
  27.             </props>  
  28.         </property>  
  29.         <property name=“testQuery” value=“select 1” />  
  30.         <property name=“poolSize”>  
  31.             <value>{poolsize}</span><span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"maxPoolSize"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>{maxPoolSize}</value>  
  32.         </property>  
  33.         <property name=“borrowConnectionTimeout”><value>{borrowConnectionTimeout}</span><span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">bean</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">bean</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"db1"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.atomikos.jdbc.AtomikosDataSourceBean"</span><span>&nbsp;</span><span class="attribute">init-method</span><span>=</span><span class="attribute-value">"init"</span><span>&nbsp;</span><span class="attribute">destroy-method</span><span>=</span><span class="attribute-value">"close"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"uniqueResourceName"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>mysql/db1</span><span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"xaDataSourceClassName"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>{jta.driver.className}</value>  
  34.         </property>  
  35.         <property name=“xaProperties”>  
  36.             <props>  
  37.                 <prop key=“url”>{db1.jdbc.driver.url}</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"user"</span><span class="tag">&gt;</span><span>{company.sql.user.name}</prop>  
  38.                 <prop key=“password”>{company.sql.user.password}</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">props</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"testQuery"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"select&nbsp;1"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"poolSize"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>{poolsize}</value>  
  39.         </property>  
  40.         <property name=“maxPoolSize”>  
  41.             <value>{maxPoolSize}</span><span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"borrowConnectionTimeout"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>{borrowConnectionTimeout}</value></property>  
  42.     </bean>  
  43.     <bean id=“db2” class=“com.atomikos.jdbc.AtomikosDataSourceBean” init-method=“init” destroy-method=“close”>  
  44.         <property name=“uniqueResourceName”>  
  45.             <value>mysql/db2</value>  
  46.         </property>  
  47.         <property name=“xaDataSourceClassName”>  
  48.             <value>{jta.driver.className}</span><span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"xaProperties"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">props</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"url"</span><span class="tag">&gt;</span><span>{db2.jdbc.driver.url}</prop>  
  49.                 <prop key=“user”>{company.sql.user.name}</span><span class="tag">&lt;/</span><span class="tag-name">prop</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">prop</span><span>&nbsp;</span><span class="attribute">key</span><span>=</span><span class="attribute-value">"password"</span><span class="tag">&gt;</span><span>{company.sql.user.password}</prop>  
  50.             </props>  
  51.         </property>  
  52.         <property name=“testQuery” value=“select 1” />  
  53.         <property name=“poolSize”>  
  54.             <value>{poolsize}</span><span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">property</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">property</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"maxPoolSize"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>{maxPoolSize}</value>  
  55.         </property>  
  56.         <property name=“borrowConnectionTimeout”><value>${borrowConnectionTimeout}</value></property>  
  57.     </bean>  
  58.       
  59.     <bean id=“dataSource” class=“com.ssi.datasource.DynamicDataSource”>  
  60.         <property name=“targetDataSources”>  
  61.             <map key-type=“java.lang.String”>  
  62.                 <entry key=“db1” value-ref=“db1” />  
  63.                 <entry key=“db2” value-ref=“db2” />  
  64.                 <entry key=“center” value-ref=“center” />  
  65.             </map>  
  66.         </property>  
  67.         <property name=“defaultTargetDataSource” ref=“center” />  
  68.     </bean>  
  69. </beans>  
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <!--指定Spring配置中用到的属性文件-->
    <bean id="propertyConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>
    <!-- JTA 数据源配置 -->
    <bean id="center" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
        <property name="uniqueResourceName">
            <value>mysql/center</value>
        </property>
        <property name="xaDataSourceClassName">
            <value>${jta.driver.className}</value>
        </property>
        <property name="xaProperties">
            <props>
                <prop key="url">${center.jdbc.driver.url}</prop>
                <prop key="user">${center.sql.user.name}</prop>
                <prop key="password">${center.sql.user.password}</prop>
            </props>
        </property>
        <property name="testQuery" value="select 1" />
        <property name="poolSize">
            <value>${poolsize}</value>
        </property>
        <property name="maxPoolSize">
            <value>${maxPoolSize}</value>
        </property>
        <property name="borrowConnectionTimeout"><value>${borrowConnectionTimeout}</value></property>
    </bean>

    <bean id="db1" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
        <property name="uniqueResourceName">
            <value>mysql/db1</value>
        </property>
        <property name="xaDataSourceClassName">
            <value>${jta.driver.className}</value>
        </property>
        <property name="xaProperties">
            <props>
                <prop key="url">${db1.jdbc.driver.url}</prop>
                <prop key="user">${company.sql.user.name}</prop>
                <prop key="password">${company.sql.user.password}</prop>
            </props>
        </property>
        <property name="testQuery" value="select 1" />
        <property name="poolSize">
            <value>${poolsize}</value>
        </property>
        <property name="maxPoolSize">
            <value>${maxPoolSize}</value>
        </property>
        <property name="borrowConnectionTimeout"><value>${borrowConnectionTimeout}</value></property>
    </bean>
    <bean id="db2" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
        <property name="uniqueResourceName">
            <value>mysql/db2</value>
        </property>
        <property name="xaDataSourceClassName">
            <value>${jta.driver.className}</value>
        </property>
        <property name="xaProperties">
            <props>
                <prop key="url">${db2.jdbc.driver.url}</prop>
                <prop key="user">${company.sql.user.name}</prop>
                <prop key="password">${company.sql.user.password}</prop>
            </props>
        </property>
        <property name="testQuery" value="select 1" />
        <property name="poolSize">
            <value>${poolsize}</value>
        </property>
        <property name="maxPoolSize">
            <value>${maxPoolSize}</value>
        </property>
        <property name="borrowConnectionTimeout"><value>${borrowConnectionTimeout}</value></property>
    </bean>

    <bean id="dataSource" class="com.ssi.datasource.DynamicDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="db1" value-ref="db1" />
                <entry key="db2" value-ref="db2" />
                <entry key="center" value-ref="center" />
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="center" />
    </bean>
</beans>


DynamicSqlClientDaoSupport.Java

  1. package com.ssi.dao;  
  2.   
  3. import java.util.Map;  
  4.   
  5. import javax.sql.DataSource;  
  6.   
  7. import org.springframework.beans.factory.InitializingBean;  
  8. import org.springframework.dao.support.DaoSupport;  
  9. import org.springframework.orm.ibatis.SqlMapClientTemplate;  
  10. import org.springframework.util.Assert;  
  11.   
  12. import com.ibatis.sqlmap.client.SqlMapClient;  
  13. import com.ssi.datasource.DbContextHolder;  
  14.   
  15. public class DynamicSqlClientDaoSupport extends DaoSupport implements InitializingBean{  
  16.   
  17.     private SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate();  
  18.     private Map<String,SqlMapClient> targetSqlMapClients;  
  19.     private SqlMapClient defaultSqlMapClient;  
  20.     private boolean externalTemplate = false;  
  21.   
  22.       
  23.     /** 
  24.      * Set the JDBC DataSource to be used by this DAO. 
  25.      * Not required: The SqlMapClient might carry a shared DataSource. 
  26.      * @see #setSqlMapClient 
  27.      */  
  28.     public final void setDataSource(DataSource dataSource) {  
  29.         if (!this.externalTemplate) {  
  30.         this.sqlMapClientTemplate.setDataSource(dataSource);  
  31.         }  
  32.     }  
  33.   
  34.     /** 
  35.      * Return the JDBC DataSource used by this DAO. 
  36.      */  
  37.     public final DataSource getDataSource() {  
  38.         return this.sqlMapClientTemplate.getDataSource();  
  39.     }  
  40.   
  41.     /** 
  42.      * Set the iBATIS Database Layer SqlMapClient to work with. 
  43.      * Either this or a “sqlMapClientTemplate” is required. 
  44.      * @see #setSqlMapClientTemplate 
  45.      */  
  46.     public final void setSqlMapClient(SqlMapClient sqlMapClient) {  
  47.         if (!this.externalTemplate) {  
  48.             this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient);  
  49.         }  
  50.     }  
  51.   
  52.     /** 
  53.      * Return the iBATIS Database Layer SqlMapClient that this template works with. 
  54.      */  
  55.     public final SqlMapClient getSqlMapClient() {  
  56.         return this.sqlMapClientTemplate.getSqlMapClient();  
  57.     }  
  58.   
  59.     /** 
  60.      * Set the SqlMapClientTemplate for this DAO explicitly, 
  61.      * as an alternative to specifying a SqlMapClient. 
  62.      * @see #setSqlMapClient 
  63.      */  
  64.     public final void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) {  
  65.         Assert.notNull(sqlMapClientTemplate, ”SqlMapClientTemplate must not be null”);  
  66.         this.sqlMapClientTemplate = sqlMapClientTemplate;  
  67.         this.externalTemplate = true;  
  68.     }  
  69.   
  70.     /** 
  71.      * Return the SqlMapClientTemplate for this DAO, 
  72.      * pre-initialized with the SqlMapClient or set explicitly. 
  73.      */  
  74.     public final SqlMapClientTemplate getSqlMapClientTemplate() {  
  75.       String dbtype = DbContextHolder.getDbType();  
  76.       if(targetSqlMapClients!=null&&targetSqlMapClients.containsKey(dbtype)){  
  77.           SqlMapClient sqlMapClient = targetSqlMapClients.get(dbtype);  
  78.           sqlMapClientTemplate = new SqlMapClientTemplate(sqlMapClient);  
  79.       }  
  80.       return this.sqlMapClientTemplate;  
  81.     }  
  82.   
  83.     @Override  
  84.     protected final void checkDaoConfig() {  
  85.         if (!this.externalTemplate) {  
  86.             this.sqlMapClientTemplate.afterPropertiesSet();  
  87.         }  
  88.     }  
  89.   
  90.     public Map<String, SqlMapClient> getTargetSqlMapClients() {  
  91.         return targetSqlMapClients;  
  92.     }  
  93.   
  94.     public void setTargetSqlMapClients(Map<String, SqlMapClient> targetSqlMapClients) {  
  95.         this.targetSqlMapClients = targetSqlMapClients;  
  96.     }  
  97.   
  98.     public SqlMapClient getDefaultSqlMapClient() {  
  99.         return defaultSqlMapClient;  
  100.     }  
  101.   
  102.     public void setDefaultSqlMapClient(SqlMapClient defaultSqlMapClient) {  
  103.         this.defaultSqlMapClient = defaultSqlMapClient;  
  104.     }  
  105. }  
package com.ssi.dao;

import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.support.DaoSupport;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.util.Assert;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.ssi.datasource.DbContextHolder;

public class DynamicSqlClientDaoSupport extends DaoSupport implements InitializingBean{

    private SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate();
    private Map<String,SqlMapClient> targetSqlMapClients;
    private SqlMapClient defaultSqlMapClient;
    private boolean externalTemplate = false;


    /**
     * Set the JDBC DataSource to be used by this DAO.
     * Not required: The SqlMapClient might carry a shared DataSource.
     * @see #setSqlMapClient
     */
    public final void setDataSource(DataSource dataSource) {
        if (!this.externalTemplate) {
        this.sqlMapClientTemplate.setDataSource(dataSource);
        }
    }

    /**
     * Return the JDBC DataSource used by this DAO.
     */
    public final DataSource getDataSource() {
        return this.sqlMapClientTemplate.getDataSource();
    }

    /**
     * Set the iBATIS Database Layer SqlMapClient to work with.
     * Either this or a "sqlMapClientTemplate" is required.
     * @see #setSqlMapClientTemplate
     */
    public final void setSqlMapClient(SqlMapClient sqlMapClient) {
        if (!this.externalTemplate) {
            this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient);
        }
    }

    /**
     * Return the iBATIS Database Layer SqlMapClient that this template works with.
     */
    public final SqlMapClient getSqlMapClient() {
        return this.sqlMapClientTemplate.getSqlMapClient();
    }

    /**
     * Set the SqlMapClientTemplate for this DAO explicitly,
     * as an alternative to specifying a SqlMapClient.
     * @see #setSqlMapClient
     */
    public final void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) {
        Assert.notNull(sqlMapClientTemplate, "SqlMapClientTemplate must not be null");
        this.sqlMapClientTemplate = sqlMapClientTemplate;
        this.externalTemplate = true;
    }

    /**
     * Return the SqlMapClientTemplate for this DAO,
     * pre-initialized with the SqlMapClient or set explicitly.
     */
    public final SqlMapClientTemplate getSqlMapClientTemplate() {
      String dbtype = DbContextHolder.getDbType();
      if(targetSqlMapClients!=null&&targetSqlMapClients.containsKey(dbtype)){
          SqlMapClient sqlMapClient = targetSqlMapClients.get(dbtype);
          sqlMapClientTemplate = new SqlMapClientTemplate(sqlMapClient);
      }
      return this.sqlMapClientTemplate;
    }

    @Override
    protected final void checkDaoConfig() {
        if (!this.externalTemplate) {
            this.sqlMapClientTemplate.afterPropertiesSet();
        }
    }

    public Map<String, SqlMapClient> getTargetSqlMapClients() {
        return targetSqlMapClients;
    }

    public void setTargetSqlMapClients(Map<String, SqlMapClient> targetSqlMapClients) {
        this.targetSqlMapClients = targetSqlMapClients;
    }

    public SqlMapClient getDefaultSqlMapClient() {
        return defaultSqlMapClient;
    }

    public void setDefaultSqlMapClient(SqlMapClient defaultSqlMapClient) {
        this.defaultSqlMapClient = defaultSqlMapClient;
    }
}
IbatisDaoSupport.java

  1. package com.ssi.dao;  
  2.   
  3. import java.io.Serializable;  
  4. import java.sql.SQLException;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. import org.apache.commons.logging.Log;  
  9. import org.apache.commons.logging.LogFactory;  
  10. import org.springframework.orm.ibatis.SqlMapClientCallback;  
  11.   
  12. import com.ibatis.sqlmap.client.SqlMapExecutor;  
  13. @SuppressWarnings(“unchecked”)  
  14. public class IbatisDaoSupport<Entity> extends DynamicSqlClientDaoSupport implements IEntityDao<Entity> {  
  15.   
  16.     protected final Log log = LogFactory.getLog(getClass());  
  17.   
  18.   
  19.     public Entity get(String sqlId, Serializable id) {  
  20.         return (Entity) getSqlMapClientTemplate().queryForObject(sqlId, id);  
  21.     }  
  22.     public Entity getByParamMap(String sqlId, Object param) {  
  23.         return (Entity) getSqlMapClientTemplate().queryForObject(sqlId, param);  
  24.     }  
  25.     public Object save(String sqlId, Object o) {  
  26.         return getSqlMapClientTemplate().insert(sqlId, o);  
  27.     }  
  28.     public Object batchSave(final String sqlId,final List<Entity> entityList) throws Exception{     
  29.         // 执行回调     
  30.         return getSqlMapClientTemplate().execute(new SqlMapClientCallback() {     
  31.             // 实现回调接口     
  32.             public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException{     
  33.                 // 开始批处理     
  34.                 executor.startBatch();     
  35.                 for (Entity entity : entityList) {     
  36.                     executor.insert(sqlId, entity);     
  37.                 }     
  38.                 return executor.executeBatch();     
  39.             }  
  40.   
  41.         });     
  42.         
  43.     }   
  44.     public Integer remove(String sqlId, Object o) {  
  45.         return getSqlMapClientTemplate().delete(sqlId, o);  
  46.   
  47.     }  
  48.   
  49.     public Integer removeById(String sqlId, Serializable id) {  
  50.         return getSqlMapClientTemplate().delete(sqlId, id);  
  51.     }  
  52.   
  53.     public Integer update(String sqlId, Object o) {  
  54.         return getSqlMapClientTemplate().update(sqlId, o);  
  55.   
  56.     }  
  57.     public Long totalCount(String sqlId, Object o){  
  58.         return (Long) getSqlMapClientTemplate().queryForObject(sqlId, o);  
  59.     }  
  60.     public List<Entity> pagedList(String sqlId, Map<String, Object> map,int pageSize, int pageNum) {  
  61.         int start = (pageNum - 1) * pageSize;  
  62.         map.put(”start”, start);  
  63.         map.put(”pageSize”, pageSize);  
  64.         List<Entity> list = getSqlMapClientTemplate().queryForList(sqlId, map);  
  65.         return list;  
  66.     }  
  67.     public List<Entity> list(String sqlId,Object o){  
  68.         return getSqlMapClientTemplate().queryForList(sqlId,o);  
  69.     }  
  70.     public List<Entity> list(String sqlId){  
  71.         return getSqlMapClientTemplate().queryForList(sqlId);  
  72.     }  
  73.   
  74. }  
package com.ssi.dao;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ibatis.SqlMapClientCallback;

import com.ibatis.sqlmap.client.SqlMapExecutor;
@SuppressWarnings("unchecked")
public class IbatisDaoSupport<Entity> extends DynamicSqlClientDaoSupport implements IEntityDao<Entity> {

    protected final Log log = LogFactory.getLog(getClass());


    public Entity get(String sqlId, Serializable id) {
        return (Entity) getSqlMapClientTemplate().queryForObject(sqlId, id);
    }
    public Entity getByParamMap(String sqlId, Object param) {
        return (Entity) getSqlMapClientTemplate().queryForObject(sqlId, param);
    }
    public Object save(String sqlId, Object o) {
        return getSqlMapClientTemplate().insert(sqlId, o);
    }
    public Object batchSave(final String sqlId,final List<Entity> entityList) throws Exception{   
        // 执行回调   
        return getSqlMapClientTemplate().execute(new SqlMapClientCallback() {   
            // 实现回调接口   
            public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException{   
                // 开始批处理   
                executor.startBatch();   
                for (Entity entity : entityList) {   
                    executor.insert(sqlId, entity);   
                }   
                return executor.executeBatch();   
            }

        });   

    } 
    public Integer remove(String sqlId, Object o) {
        return getSqlMapClientTemplate().delete(sqlId, o);

    }

    public Integer removeById(String sqlId, Serializable id) {
        return getSqlMapClientTemplate().delete(sqlId, id);
    }

    public Integer update(String sqlId, Object o) {
        return getSqlMapClientTemplate().update(sqlId, o);

    }
    public Long totalCount(String sqlId, Object o){
        return (Long) getSqlMapClientTemplate().queryForObject(sqlId, o);
    }
    public List<Entity> pagedList(String sqlId, Map<String, Object> map,int pageSize, int pageNum) {
        int start = (pageNum - 1) * pageSize;
        map.put("start", start);
        map.put("pageSize", pageSize);
        List<Entity> list = getSqlMapClientTemplate().queryForList(sqlId, map);
        return list;
    }
    public List<Entity> list(String sqlId,Object o){
        return getSqlMapClientTemplate().queryForList(sqlId,o);
    }
    public List<Entity> list(String sqlId){
        return getSqlMapClientTemplate().queryForList(sqlId);
    }

}




UserDaoImpl.java:

  1. package com.ssi.dao.impl;  
  2.   
  3. import org.springframework.stereotype.Repository;  
  4.   
  5.   
  6. import com.ssi.dao.IUserDao;  
  7. import com.ssi.dao.IbatisDaoSupport;  
  8. import com.ssi.model.User;  
  9. @Repository(“userDao”)  
  10. public class UserDaoImpl extends IbatisDaoSupport<User> implements IUserDao {  
  11.     public Integer addUser(User user) throws Exception{  
  12.         return (Integer) this.save(“User.insert”, user);  
  13.     }  
  14. }  
package com.ssi.dao.impl;

import org.springframework.stereotype.Repository;


import com.ssi.dao.IUserDao;
import com.ssi.dao.IbatisDaoSupport;
import com.ssi.model.User;
@Repository("userDao")
public class UserDaoImpl extends IbatisDaoSupport<User> implements IUserDao {
    public Integer addUser(User user) throws Exception{
        return (Integer) this.save("User.insert", user);
    }
}


 

UserServiceImpl.java

  1. package com.ssi.service.impl;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.springframework.stereotype.Service;  
  6.   
  7. import com.ssi.dao.IUserDao;  
  8. import com.ssi.datasource.DbContextHolder;  
  9. import com.ssi.model.User;  
  10. import com.ssi.service.IUserService;  
  11.   
  12.   
  13. @Service(“userService”)  
  14. public class UserServiceImpl implements IUserService {  
  15.     @Resource private IUserDao userDao;  
  16.     /** 
  17.      * 测试在service中切换数据源 异常是否回滚 
  18.      */  
  19.     public void addUser(User user) throws Exception{  
  20.         DbContextHolder.setDbType(”db1”);     
  21.         userDao.addUser(user);  
  22.         DbContextHolder.setDbType(”db2”);    
  23.         user.setUserName(”user2”);  
  24.         userDao.addUser(user);  
  25.         DbContextHolder.setDbType(”center”);  
  26.         user.setUserName(”user3”);  
  27.         userDao.addUser(user);  
  28.         //System.out.println(1/0);  
  29.     }  
  30. }  
package com.ssi.service.impl;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.ssi.dao.IUserDao;
import com.ssi.datasource.DbContextHolder;
import com.ssi.model.User;
import com.ssi.service.IUserService;


@Service("userService")
public class UserServiceImpl implements IUserService {
    @Resource private IUserDao userDao;
    /**
     * 测试在service中切换数据源 异常是否回滚
     */
    public void addUser(User user) throws Exception{
        DbContextHolder.setDbType("db1");   
        userDao.addUser(user);
        DbContextHolder.setDbType("db2");  
        user.setUserName("user2");
        userDao.addUser(user);
        DbContextHolder.setDbType("center");
        user.setUserName("user3");
        userDao.addUser(user);
        //System.out.println(1/0);
    }
}


DynamicDataSource.java:

  1. public class DynamicDataSource extends AbstractRoutingDataSource {  
  2.   
  3.     static Logger log = Logger.getLogger(DynamicDataSource.class);  
  4.   
  5.     protected Object determineCurrentLookupKey() {  
  6.         return DbContextHolder.getDbType();  
  7.     }  
  8.   
  9. }  
public class DynamicDataSource extends AbstractRoutingDataSource {

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

    protected Object determineCurrentLookupKey() {
        return DbContextHolder.getDbType();
    }

}
DbContextHolder.java:

  1. public class DbContextHolder {  
  2.     private static final ThreadLocal contextHolder = new ThreadLocal();  
  3.   
  4.     public static void setDbType(String dbType) {  
  5.         contextHolder.set(dbType);  
  6.     }  
  7.   
  8.     public static String getDbType() {  
  9.         return (String) contextHolder.get();  
  10.     }  
  11.   
  12.     public static void clearDbType() {  
  13.         contextHolder.remove();  
  14.     }  
  15.   
  16. }  
public class DbContextHolder {
    private static final ThreadLocal contextHolder = new ThreadLocal();

    public static void setDbType(String dbType) {
        contextHolder.set(dbType);
    }

    public static String getDbType() {
        return (String) contextHolder.get();
    }

    public static void clearDbType() {
        contextHolder.remove();
    }

}


三个数据库:dbcenter、db1、db2 表结构均相同 

脚本:

  1. DROP TABLE IF EXISTS `tb_user`;  
  2.   
  3. CREATE TABLE `tb_user` (  
  4.   `id` int(11) NOT NULL AUTO_INCREMENT,  
  5.   `userName` varchar(20) DEFAULT NULL,  
  6.   `passwordvarchar(60) DEFAULT NULL,  
  7.   PRIMARY KEY (`id`)  
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
DROP TABLE IF EXISTS `tb_user`;

CREATE TABLE `tb_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userName` varchar(20) DEFAULT NULL,
  `password` varchar(60) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

单元测试

  1. public class JunitTest{    
  2.     public ApplicationContext cxt;  
  3.     @Test  
  4.     public void init() throws Exception{  
  5.         cxt = new ClassPathXmlApplicationContext(new String[] {“applicationContext.xml”,“applicationContext-datasource.xml”});  
  6.         testInsertUser();  
  7.   
  8.     }  
  9.       
  10.       
  11.     private void testInsertUser() throws Exception{  
  12.         IUserService userService = (IUserService)cxt.getBean(”userService”);  
  13.         User user = new User();  
  14.         user.setUserName(”user1”);  
  15.         user.setPassword(”0”);  
  16.         userService.addUser(user);  
  17.     }  
  18.       
  19.     private void testInsertUser2() throws Exception{  
  20.       
  21. }    
public class JunitTest{  
    public ApplicationContext cxt;
    @Test
    public void init() throws Exception{
        cxt = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml","applicationContext-datasource.xml"});
        testInsertUser();

    }


    private void testInsertUser() throws Exception{
        IUserService userService = (IUserService)cxt.getBean("userService");
        User user = new User();
        user.setUserName("user1");
        user.setPassword("0");
        userService.addUser(user);
    }

    private void testInsertUser2() throws Exception{

}  





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值