atomikos和Mybatis分布式事务

本项目基于maven,使用spring,mybatis 首先pom.xml引入`

<!-- 多数据源事务管理 -->

    <dependency>
        <groupId>com.atomikos</groupId>
        <artifactId>transactions-jdbc</artifactId>
        <version>3.9.3</version>
    </dependency>

    <dependency>
        <groupId>com.atomikos</groupId>
        <artifactId>transactions-jta</artifactId>
        <version>3.9.3</version>
    </dependency>

    <dependency>
        <groupId>com.atomikos</groupId>
        <artifactId>transactions</artifactId>
        <version>3.9.3</version>
    </dependency>

    <dependency>
        <groupId>com.atomikos</groupId>
        <artifactId>transactions-api</artifactId>
        <version>3.9.3</version>
    </dependency>

    <dependency>
        <groupId>com.atomikos</groupId>
        <artifactId>atomikos-util</artifactId>
        <version>3.9.3</version>
    </dependency>

    <dependency>
    <groupId>javax.transaction</groupId>
    <artifactId>jta</artifactId>
    <version>1.1</version></dependency>

spring-mybatis.xml配置数据库以及事务管理

    <!-- 分别配置2个数据库的dataSource,以mysql为例 -->
<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
        init-method="init" destroy-method="close">
        <property name="uniqueResourceName" value="ds1" />
        <property name="xaDataSourceClassName"
            value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
        <property name="xaProperties">
            <props>
                <prop key="url">${dataSource1.url}</prop>
                <prop key="user">${dataSource1.username}</prop>
                <prop key="password">${dataSource1.password}</prop>
            </props>
        </property>
        <property name="minPoolSize" value="${minPoolSize}" />
        <property name="maxPoolSize" value="${maxPoolSize}" />
        <property name="borrowConnectionTimeout" value="${borrowConnectionTimeout}" />
        <property name="testQuery" value="select 1" />
        <property name="maintenanceInterval" value="60" />
    </bean>

     <bean id="dataSource2" class="com.atomikos.jdbc.AtomikosDataSourceBean"
        init-method="init" destroy-method="close">

        <property name="uniqueResourceName" value="ds2" />
        <property name="xaDataSourceClassName"
            value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
        <property name="xaProperties">
            <props>
                <prop key="url">${dataSource2.url}</prop>
                <prop key="user">${dataSource2.username}</prop>
                <prop key="password">${dataSource2.password}</prop>
            </props>
        </property>
        <property name="minPoolSize" value="${minPoolSize}" />
        <property name="maxPoolSize" value="${maxPoolSize}" />
        <property name="borrowConnectionTimeout" value="${borrowConnectionTimeout}" />
        <property name="testQuery" value="select 1" />
        <property name="maintenanceInterval" value="60" />
    </bean>    
<!-- 分别配置2个数据库的sqlSessionFactory,以及mybatis的一些mapper扫描配置,未使用mybatis可做相关修改 -->
 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath*:com/core/dao/impl/mysql/mapping/**/*.xml" />
          <property name="typeAliasesPackage" value="com.core.entity,com.core.dto" />
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.core.dao.interfaces" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>


 <bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource2" />
        <property name="mapperLocations" value="classpath*:com/core/dao2/impl/mysql/mapping/**/*.xml" />
          <property name="typeAliasesPackage" value="com.core.entity2,com.core.dto2" />
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2" />
        <property name="basePackage" value="com.core.dao2.interfaces" />
    </bean> 
<!-- 事务配置 -->
    <bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp"
        init-method="init" destroy-method="shutdownForce">
        <constructor-arg>
            <props>
                <prop key="com.atomikos.icatch.service">com.atomikos.icatch.standalone.UserTransactionServiceFactory
                </prop>
            </props>
        </constructor-arg>
    </bean>
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
        init-method="init" destroy-method="close" depends-on="userTransactionService">
        <property name="forceShutdown" value="false" />
    </bean>
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"
        depends-on="userTransactionService">
        <property name="transactionTimeout" value="300" />
    </bean>
    <bean id="jtaTransactionManager"
        class="org.springframework.transaction.jta.JtaTransactionManager"
        depends-on="userTransactionService">
        <property name="transactionManager" ref="atomikosTransactionManager" />
        <property name="userTransaction" ref="atomikosUserTransaction" />
    </bean>
    <tx:annotation-driven transaction-manager="jtaTransactionManager" />

数据库配置jdbc.properties

dataSource1.driver=com.mysql.jdbc.Driver
dataSource1.url=jdbc:mysql://x.x.x.x:3306/db_mars?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=falsedataSource1.username=xxxxxx
dataSource1.password=xxxxxx


dataSource2.driver=com.mysql.jdbc.Driver
dataSource2.url=jdbc:mysql://x.x.x.x:3306/merchant?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=falsedataSource2.username=xxxx
dataSource2.password=xxxxx

然后在.方法或者类上添加注解

@Transactional(rollbackFor = Exception.class)

可以测试一下

    @Override
    public void Test() {
        Member m=new Member();//BD1  任意写一个对象
        m.setUserName("yyyyyyyyyyyyyyyy");
        memberDao.insertSelective(m);//DB1 插入数据库
        User e=new User();//DB2 任意写一个对象
        e.setLoginName("yyyyyyyyyyyyyyyyyyy");
        userDao.insertSelective(e);//DB2 插入数据库

        User u=null;//制造一个空指针
        u.getId();
    }

配置jta.properties

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory  com.atomikos.icatch.console_file_name = tm.out  com.atomikos.icatch.log_base_name = tmlog  
com.atomikos.icatch.tm_unique_name = com.atomikos.spring.jdbc.tmcom.atomikos.icatch.console_log_level = ERROR 
`

项目启动后,atomikos生成日志并锁定日志文件,部署项目时,在同一个tomcat或者jetty下避免文件名称相同.


你可能感兴趣的:(atomikos,分布式事务,mybatis多库事务,java多库事务)