• SpringMvc + Mybatis项目中 使用 Atomikos实现分布式事务


    背景:项目架构使用了SpringMvc + Mybatis,同时在使用多数据源的时候需要满足事务一致性

      通俗的说法是:项目中配置了多个数据源,并且在一个service方法中使用多个数据源的时候需要保证事务一致性。

      网上的主流资料大概讲解了两种spring对分布式事务的实现:jotm和Atomikos,需要注意的是使用jotm的时候需要用到一个类org.springframework.transaction.jta.JotmFactoryBean然而在spring 3.x之后移除了这个类,所以我采用了Atomikos的方式。

      实现过程如下:

      1、在使用了Atomikos之后需要注意DataSource不能再使用c3p0 之类的驱动了,需要用到com.atomikos.jdbc.AtomikosDataSourceBean,下面是两个DataSource的配置示例:

      

     1 <bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
     2         <property name="uniqueResourceName" value="XA1DBMS1" />  
     3         <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />  
     4         <property name="xaProperties">  
     5             <props>  
     6                 <prop key="URL">${dataPortal_mysql_jdbc_url}</prop>  
     7                 <prop key="user">${dataPortal_mysql_jdbc_user}</prop>  
     8                 <prop key="password">${dataPortal_mysql_jdbc_password}</prop>  
     9             </props>  
    10         </property>  
    11         <property name="poolSize" value="3" />  
    12         <property name="minPoolSize" value="3" />  
    13         <property name="maxPoolSize" value="5" />
    14     </bean>
    15     
    16     <bean id="webDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
    17         <property name="uniqueResourceName" value="XA1DBMS2" />  
    18         <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />  
    19         <property name="xaProperties">  
    20             <props>  
    21                 <prop key="URL">${web.jdbc.url}</prop>  
    22                 <prop key="user">${web.jdbc.username}</prop>  
    23                 <prop key="password">${web.jdbc.password}</prop>  
    24             </props>  
    25         </property>  
    26         <property name="poolSize" value="3" />  
    27         <property name="minPoolSize" value="3" />  
    28         <property name="maxPoolSize" value="5" />
    29     </bean>

     这里一些其他的参数,比如最大连接数,超时时间的参数我是在com.atomikos.jdbc.AtomikosDataSourceBean源码中找到的:

     

    两个DataSource中webDataSource我采用的是spring的JdbcTemplate去写sql而dataSource则配置使用了mybatis的方式

    2、两种不同的方式配置如下:

     1 <!-- web库jdbcTemplate -->
     2     <bean id="webJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     3         <property name="dataSource" ref="webDataSource" />
     4     </bean>
     5     <!-- gmt库jdbcTemplate -->
     6     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     7         <property name="dataSource">
     8             <ref bean="dataSource" />
     9         </property>
    10     </bean>
    11     
    12     <!-- 创建SqlSessionFactory,同时指定数据源 -->
    13     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    14         <property name="dataSource" ref="dataSource" />
    15         <property name="mapperLocations"  value="classpath:com/sincetimes/modernship/**/dao/*.xml"/>
    16     </bean>
    17     
    18     <!-- mybatis自动扫描器 -->
    19     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    20         <property name="basePackage" value="com.sincetimes.modernship.dao" />
    21         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    22     </bean>
    23     
    24     <!-- DAO使用mybatis进行数据库访问操作 -->
    25     <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    26         <constructor-arg index="0" ref="sqlSessionFactory" />
    27     </bean>

    3、在配置事务的时候,我们可以使用@Transactional注解,也可以写aop

     1 <!-- 分布式事务 -->
     2     <bean id="userTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">  
     3         <property name="transactionTimeout" value="300" />  
     4     </bean>  
     5 
     6     <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">  
     7         <property name="userTransaction" ref="userTransaction" />   
     8     </bean>
     9 
    10     <tx:annotation-driven transaction-manager="springTransactionManager"/>
    11 
    12     <aop:config>
    13         <aop:pointcut id="baseServiceMethods" expression="execution(* com.sincetimes..impl..*.*(..))" />
    14         <aop:advisor pointcut-ref="baseServiceMethods" advice-ref="txAdvice"/>
    15     </aop:config>
    16 
    17     <!-- 配置事务的传播特性 -->
    18     <tx:advice id="txAdvice" transaction-manager="springTransactionManager">
    19         <tx:attributes>
    20             <tx:method name="query*" propagation="REQUIRED" read-only="true" />
    21             <tx:method name="get*" propagation="REQUIRED" read-only="true" />
    22             <tx:method name="find*" propagation="REQUIRED" read-only="true" />
    23             <tx:method name="list*" propagation="REQUIRED" read-only="true" />
    24             <tx:method name="count*" propagation="REQUIRED" read-only="true" />
    25             <tx:method name="insert*" propagation="REQUIRED" />
    26             <tx:method name="add*" propagation="REQUIRED" />
    27             <tx:method name="del*" propagation="REQUIRED" />
    28             <tx:method name="save*" propagation="REQUIRED" />
    29             <tx:method name="update*" propagation="REQUIRED" />
    30             <tx:method name="edit*" propagation="REQUIRED" />
    31             <tx:method name="enable*" propagation="REQUIRED" />                
    32             <tx:method name="upload*" propagation="REQUIRED" />                
    33         </tx:attributes>
    34     </tx:advice>

    分布式事务中的重点是事务管理器。在Atomikos中对应的就是 com.atomikos.icatch.jta.UserTransactionManager 

    4、如果项目使用了log4j的话,并且日志级别为info,在项目启动后会发现有很多atomikos的info日志打印出来,这个时候在log4j的配置文件中增加一个配置:log4j.logger.com.atomikos = error 即可。

    这里参考了网上找到的资料:https://my.oschina.net/pingpangkuangmo/blog/413518

  • 相关阅读:
    Asp.net 自定义config文件读取
    sql 两个数字范围取随机数
    数据库中一些简单的防刷机制
    sql日期操作收集
    全文索引工作收集
    JQuery Div滚动条插件 jScroll
    OLE DB 访问接口 'Microsoft.Jet.OLEDB.4.0' 配置为在单线程单元模式下运行,所以该访问接口无法用于分布式查询
    vs 高级保存选项的设置
    Web.config配置文件详解
    JS,Jquery获取各种屏幕的宽度和高度
  • 原文地址:https://www.cnblogs.com/FlyHeLanMan/p/7767678.html
Copyright © 2020-2023  润新知