• Spring+JTA+Atomikos+MyBatis分布式事务管理


       我们平时的工作中用到的Spring事务管理是管理一个数据源的。但是如果对多个数据源进行事务管理该怎么办呢?我们可以用JTA和Atomikos结合Spring来实现一个分布式事务管理的功能。了解JTA可以看一下这篇文章。下面我们看怎么实现分布式事务的。

      步骤一:添加pom.xml依赖

      步骤二:准备配置文件。jdbc.properties,jta.properties

    jdbc.properties

    jdbc.driver=com.mysql.jdbc.Driver
    
    jdbc.one.url=jdbc:mysql://127.0.0.1:3306/zsyy-pt-ls?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
    jdbc.one.username=root
    jdbc.one.password=esbmysql@ucmed.com
    
    jdbc.two.url=jdbc:mysql://127.0.0.1:3306/zsyy-pt-test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
    jdbc.two.username=root
    jdbc.two.password=esbmysql@ucmed.com

    jta.properties

    com.atomikos.icatch.registered=true
    com.atomikos.icatch.console_file_name=ls2rm.out
    com.atomikos.icatch.log_base_name=base_log
    com.atomikos.icatch.log_base_dir=lslog

     步骤三、配置两个数据源

    <bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close" abstract="true">
            <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
            <property name="poolSize" value="10"/>
            <property name="minPoolSize" value="10"/>
            <property name="maxPoolSize" value="30"/>
            <property name="borrowConnectionTimeout" value="60"/>
            <property name="reapTimeout" value="20"/>
            <property name="maxIdleTime" value="60"/>
            <property name="maintenanceInterval" value="60"/>
            <property name="testQuery">
                <value>SELECT 1</value>
            </property>
        </bean>
        <!-- 配置数据源一 -->
        <bean id="dataSourceOne" parent="abstractXADataSource">
            <property name="uniqueResourceName">
                <value>dataSourceOne</value>
            </property>
            <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
            <property name="xaProperties">
                <props>
                    <prop key="URL">${jdbc.one.url}</prop>
                    <prop key="user">${jdbc.one.username}</prop>
                    <prop key="password">${jdbc.one.password}</prop>
                </props>
            </property>
        </bean>
        <!--配置数据源二-->
        <bean id="dataSourceTwo" parent="abstractXADataSource">
            <property name="uniqueResourceName">
                <value>dataSourceTwo</value>
            </property>
            <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
            <property name="xaProperties">
                <props>
                    <prop key="URL">${jdbc.two.url}</prop>
                    <prop key="user">${jdbc.two.username}</prop>
                    <prop key="password">${jdbc.two.password}</prop>
                    <prop key="pinGlobalTxToPhysicalConnection">true</prop>
                </props>
            </property>
        </bean>

    步骤四、配置分布式事务

    <!--配置分布式事务-->
        <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
            <property name="forceShutdown" value="false"/>
        </bean>
        <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
            <property name="transactionTimeout" value="300000"/>
        </bean>
        <!--JTA事务管理器-->
        <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
            <property name="transactionManager">
                <ref bean="atomikosTransactionManager"/>
            </property>
            <property name="userTransaction">
                <ref bean="atomikosUserTransaction"/>
            </property>
            <property name="allowCustomIsolationLevels" value="true"/>
        </bean>
    
        <aop:aspectj-autoproxy />
        <!--声明式事务-->
        <aop:config proxy-target-class="true">
            <aop:advisor advice-ref="txAdvice" pointcut="execution(* org.hope.database.one.service.MemberServiceImpl.addMemberAndPoints(..))"/>
        </aop:config>
    
        <tx:advice id="txAdvice" transaction-manager="springTransactionManager">
            <tx:attributes>
                <tx:method name="add*" propagation="REQUIRED" read-only="true"/>
                <tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
            </tx:attributes>
        </tx:advice>

    步骤五、配置mybatis

    <!--mybatis的相关配置-->
        <bean id="sqlSessionFactoryOne" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSourceOne"/>
            <property name="configLocation" value="mybatis-config.xml"/>
            <property name="typeAliasesPackage" value="org.hope.database.one.model"/>
            <property name="mapperLocations">
                <list>
                    <value>classpath:mapper/one/*.xml</value>
                </list>
            </property>
        </bean>
        
        <bean id="sqlSessionFactoryTwo" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSourceTwo"/>
            <property name="configLocation" value="mybatis-config.xml"/>
            <property name="typeAliasesPackage" value="org.hope.database.two.model"/>
            <property name="mapperLocations">
                <list>
                    <value>classpath:mapper/two/*.xml</value>
                </list>
            </property>
        </bean>
        <!--配置mybatis映射文件自动扫描-->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="org.hope.database.one"/>
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryOne"/>
        </bean>
    
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="org.hope.database.two"/>
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryTwo"/>
        </bean>

    步骤六、写对应的service

      dao和model这个直接看代码吧。

    package org.hope.database.one.service;
    
    import org.hope.database.one.dao.MemberMapper;
    import org.hope.database.two.dao.PointMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    
    @Service("memberServiceWa")
    public class MemberServiceImpl implements MemberService {
    
        @Autowired
        private MemberMapper memberMapper;
    
        @Autowired
        private PointMapper pointMapper;
    
        public void addMemberAndPoints(String name, int point) {
                memberMapper.addMember(name);
                String str = null;
                str.equals("wge");//此处会出现异常
                pointMapper.addPoint(point);
        }
    }

    步骤七、单元测试

    package org.hope.service;
    
    import org.hope.database.one.service.MemberService;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath*:applicationContext.xml"})
    public class MemberServiceTest {
    
        @Autowired
        private MemberService memberServiceWa;
    
        @Test
        public void addMemberAndPointTest() {
            String name = "马化腾";
            int points = 50;
            memberServiceWa.addMemberAndPoints(name, points);
        }
    }

     https://gitee.com/huayicompany/spring-learn/tree/master/srping-jta-atomikos

    参考:

    [1] 博客,http://blog.csdn.net/zeroctu/article/details/53116351

    [2] 博客,http://blog.csdn.net/sun8288/article/details/8674016,Atomickos中文文档

  • 相关阅读:
    JS函数重载解决方案
    JavaScript开发规范
    ASP.Net中表单POST到其他页面的方法
    高效的使用 Response.Redirect
    jQuery性能优化
    百度WebUploader中实现文件上传下载的三种解决方案(推荐)
    WebUploader中实现文件上传下载的三种解决方案(推荐)
    vue中实现文件上传下载的三种解决方案(推荐)
    JavaScript中实现文件上传下载的三种解决方案(推荐)
    ST
  • 原文地址:https://www.cnblogs.com/happyflyingpig/p/8003957.html
Copyright © 2020-2023  润新知