Spring+Mybatis+Tomat多数据源(mysql+sql server)与atomikos分布式事务配置

最近刚刚转行java开发。入职第一天,要实现将数据保存到mysql和sql server数据库中,并保证事务性,各种查阅资料,以下是完成成果,记录一下:
首先是jar包引入:
关于Atomikos相关jar包:
transactions-jdbc
transactions-jta
transactions-api
transactions
atomikos-utils
关于jta包:
jta-1.1
所有jar包截图如下

jdbc.properties:

#=================================================
# MySQL
#=================================================
jdbc.mysql.driver=com.mysql.jdbc.Driver
jdbc.mysql.url=jdbc:mysql://127.0.0.1:3306/crm?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
jdbc.mysql.username=root
jdbc.mysql.password=root
#=================================================
# MS SQL Server 
#=================================================
jdbc.sqlserver.username=sa
jdbc.sqlserver.password=pwd@123
#=================================================
# 通用配置
#=================================================
jdbc.initialSize=5
jdbc.minIdle=5
jdbc.maxIdle=20
jdbc.maxActive=100
jdbc.maxWait=100000
jdbc.defaultAutoCommit=false
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=600
jdbc.testWhileIdle=true
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.numTestsPerEvictionRun=20
jdbc.minEvictableIdleTimeMillis=300000

log4j.properties

#\u5B9A\u4E49\u8F93\u51FA\u683C\u5F0F
ConversionPattern=%d %-5p [%t] %c - %m%n

log4j.rootLogger=DEBUG,Console
log4j.logger.com.cnblogs.lzrabbit=DEBUG
log4j.logger.org.springframework=ERROR
log4j.logger.org.mybatis=ERROR
log4j.logger.org.apache.ibatis=ERROR
log4j.logger.org.quartz=ERROR
log4j.logger.org.apache.axis2=ERROR
log4j.logger.org.apache.axiom=ERROR
log4j.logger.org.apache=ERROR
log4j.logger.httpclient=ERROR
#log4j.additivity.org.springframework=false
#Console 
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Threshold=DEBUG  
log4j.appender.Console.Target=System.out  
log4j.appender.Console.layout=org.apache.log4j.PatternLayout  
log4j.appender.Console.layout.ConversionPattern=${ConversionPattern}
#log4j.appender.Console.encoding=UTF-8

#org.apache.log4j.DailyRollingFileAppender
log4j.appender.DailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DailyFile.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.DailyFile.File=${myApp.root}/logs/daily.log
log4j.appender.DailyFile.Append=true
log4j.appender.DailyFile.Threshold=DEBUG
log4j.appender.DailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.DailyFile.layout.ConversionPattern=${ConversionPattern}
log4j.appender.DailyFile.encoding=UTF-8

jta.properties

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.log_base_name = jdbc
com.atomikos.icatch.tm_unique_name = com.atomikos.spring.jdbc.tm
com.atomikos.icatch.serializable_logging=false

mybatis-config.xml

<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- setting -->
    <!-- 别名 -->
    <typeAliases>
        <package name="cn.test.core.bean"/>
    </typeAliases>
    <!-- Mapper位置  注意: Dao接口与Mapper配置文件在一个目录下,并且 同名 可以不做如下配置  -->
    <!-- 
    <mappers>
        <package name="cn.test.core.dao"/>
    </mappers> 
    -->
</configuration>

application-context.xml:

<!-- 导入全部的配置文件此处方便查看在一个配置文件中 -->
<!-- <import resource="config/*.xml"/> -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
        <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>
  <!-- One -->
  <!-- XA方式  -->
    <bean id="oneDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
        <property name="uniqueResourceName" value="db_one1"/>
        <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
        <property name="xaProperties">
            <props>
                <prop key="url">${jdbc.mysql.url}</prop>
                <prop key="user">${jdbc.mysql.username}</prop>
                <prop key="password">${jdbc.mysql.password}</prop>
            </props>
        </property>
        <property name="minPoolSize" value="10" />
        <property name="maxPoolSize" value="100" />
        <property name="borrowConnectionTimeout" value="30" />
        <property name="testQuery" value="select 1" />
        <property name="maintenanceInterval" value="60" />
    </bean>

    <bean id="oneSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
         <property name="dataSource" ref="oneDataSource"/>
         <property name="configLocation" value="classpath:mybatis-config.xml"/>
         <property name="mapperLocations" value="classpath*:dao/one/*.xml"/>
    </bean>
    <!-- Two -->
    <!-- XA方式  -->
    <bean id="twoDataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
        <property name="uniqueResourceName" value="db_two2"/>
        <property name="xaDataSourceClassName" value="com.microsoft.sqlserver.jdbc.SQLServerXADataSource"/>
        <property name="xaProperties">
            <props>
                <prop key="serverName">192.168.1.122</prop>
                <prop key="databaseName">change</prop>
                <prop key="user">${jdbc.sqlserver.username}</prop>
                <prop key="password">${jdbc.sqlserver.password}</prop>
            </props>
        </property>
        <property name="minPoolSize" value="10" />
        <property name="maxPoolSize" value="100" />
        <property name="borrowConnectionTimeout" value="30" />
        <property name="testQuery" value="select 1" />
        <property name="maintenanceInterval" value="60" />
    </bean>
    <bean id="twoSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
         <property name="dataSource" ref="twoDataSource"/>
         <property name="configLocation" value="classpath:mybatis-config.xml"/>
         <property name="mapperLocations" value="classpath*:dao/two/*.xml"/>
    </bean>

    <!-- 分布式事务 -->
    <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="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="atomikosTransactionManager"/>
        <property name="userTransaction" ref="atomikosUserTransaction"/>
    </bean> 
     <tx:annotation-driven/>   
    <!-- Service  -->
    <bean id="testJtaService" class="cn.test.core.service.TestJtaServiceImpl">
        <property name="testTbDao" ref="testTbDao"></property>
        <property name="testUserDao" ref="testUserDao"></property>
    </bean> 
   <!-- Dao -->
     <bean id="testTbDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
         <property name="mapperInterface" value="cn.test.core.dao.one.TestTbDao"></property>
         <property name="sqlSessionFactory" ref="oneSqlSessionFactory"></property>
    </bean>    

     <bean id="testUserDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
         <property name="mapperInterface" value="cn.test.core.dao.two.TestUserDao"></property>
         <property name="sqlSessionFactory" ref="twoSqlSessionFactory"></property>
    </bean>    
</beans>

下面就是测试分布式事务代码:截图说明目录结构和相关文件:(忽略config目录)
这里忽略config目录
测试数据的数据表:
mysql
sql server
测试bean ,就很简单了,不做展示,提供带参数构造方法,方便测试。
按照目录结构,逐一展示其代码:
TestTbDao.java:

package cn.test.core.dao.one;
import org.springframework.stereotype.Repository;
import cn.test.core.bean.TestTb;
/**
 * 测试 Dao 接口
 * @author Barry
 */
public interface TestTbDao {
    //测试添加
    void addTestTb(TestTb testTb);
}

TestTbDao.xml:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.test.core.dao.one.TestTbDao">
    <!--  添加测试数据  -->
    <insert id="addTestTb" parameterType="TestTb">
        insert into tb_test
        (id,name)
        values
        (#{id},#{name})
    </insert>
</mapper>

TestUserDao.java:

package cn.test.core.dao.two;

import org.springframework.stereotype.Repository;

import cn.test.core.bean.TestUser;

public interface TestUserDao {
    //测试添加
    void addTestUser(TestUser testUser);
}

TestUserDao.xml:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.test.core.dao.two.TestUserDao">
    <!--  添加测试数据  -->
    <insert id="addTestUser" parameterType="cn.test.core.bean.TestUser">
        insert into tb_user
        (t_id,t_name)
        values
        (#{t_id},#{t_name})
    </insert>
</mapper>

TestJtaService.java :

public interface TestJtaService {
    void add(TestTb testTb, TestUser testUser) ;
}

TestJtaServiceImpl.java:

@Service
@Transactional
public class TestJtaServiceImpl implements TestJtaService {
    private TestTbDao testTbDao;
    private TestUserDao testUserDao;

    public void setTestTbDao(TestTbDao testTbDao) {
        this.testTbDao = testTbDao;
    }
    public void setTestUserDao(TestUserDao testUserDao) {
        this.testUserDao = testUserDao;
    }
    @Override
    public void add(TestTb testTb, TestUser testUser) {
        testTbDao.addTestTb(testTb);
        //测试分布式事务
        //int  i  = 1/0;
        testUserDao.addTestUser(testUser);
    }
}

public class TestTestTb {

     ApplicationContext context = null;
     TestJtaService testJtaService = null;

    @Before
    public void initContext(){
        this.context = new FileSystemXmlApplicationContext("classpath:application-context.xml");
        this.testJtaService = (TestJtaService) context.getBean("testJtaService");
    }

    @Test
    public void testAdd() {
        TestTb testTb = new TestTb(33,"one");
        TestUser testUser = new TestUser(33,"two");

        testJtaService.add(testTb, testUser);   
    }
}

至此所有配置和测试代码都已完成,测试去掉服务层实现类的注释即可看到效果。

参考相关:
http://loftor.com/archives/spring-mybatis-tomcat-jta.html
http://zxlaiye.iteye.com/blog/1441299

最后在提供一个maven 仓库:
https://repository.sonatype.org/index.html

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值