zoukankan      html  css  js  c++  java
  • java跨库事务Atomikos

    1:引入额外的jar

    <dependency>
                <groupId>com.atomikos</groupId>
                <artifactId>transactions-jdbc</artifactId>
                <version>4.0.6</version>
            </dependency>
            <dependency>
                <groupId>com.atomikos</groupId>
                <artifactId>transactions-jta</artifactId>
                <version>4.0.6</version>
            </dependency>
            <dependency>
                <groupId>com.atomikos</groupId>
                <artifactId>transactions-api</artifactId>
                <version>4.0.6</version>
            </dependency>
            <dependency>
                <groupId>com.atomikos</groupId>
                <artifactId>transactions</artifactId>
                <version>4.0.6</version>
            </dependency>
            <dependency>
                <groupId>com.atomikos</groupId>
                <artifactId>transactions-jms</artifactId>
                <version>4.0.6</version>
            </dependency>
            <dependency>
                <groupId>com.atomikos</groupId>
                <artifactId>atomikos-util</artifactId>
                <version>4.0.6</version>
            </dependency>
            <dependency>
                <groupId>javax.transaction</groupId>
                <artifactId>jta</artifactId>
                <version>1.1</version>
            </dependency>
        </dependencies>

    2:配制文件

    #mysql
    index.jdbc.driverClassName=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
    index.jdbc.url=jdbc:mysql://*.*.*.*:4316/k12_fee_tabindex?serverTimezone=UTC&useSSL=false&characterEncoding=UTF8
    index.jdbc.username=myhuiqu
    index.jdbc.password=Huiqu.com@123
    
    merch.jdbc.driverClassName=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
    merch.jdbc.url=jdbc:mysql://1.1.1.1.1:4316/k12_fee?serverTimezone=UTC&useSSL=false&characterEncoding=UTF8
    merch.jdbc.username=myhuiqu
    merch.jdbc.password=Huiqu.com@123
    
    user.jdbc.driverClassName=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
    user.jdbc.url=jdbc:mysql://1.1.1.1.1:4316/k12_fee_userclient?serverTimezone=UTC&useSSL=false&characterEncoding=UTF8
    user.jdbc.username=myhuiqu
    user.jdbc.password=Huiqu.com@123
    
    #active
    brokerURL=tcp://1.1.1.1:61616
    userName=admin
    password=abc123

    3:数据源配制

        spring-index-orm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:c="http://www.springframework.org/schema/c"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
        default-lazy-init="false">
    
        <context:annotation-config />
    
        <context:property-placeholder location="classpath*:/**/*.properties"
            ignore-unresolvable="true" />
    
        <context:component-scan base-package="fbs.demo">
            <context:exclude-filter type="annotation"
                expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
        
        <bean id="k12_index_dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">  
            <property name="uniqueResourceName" value="ds1"/>  
            <property name="xaDataSourceClassName" value="${index.jdbc.driverClassName}"/>  
            <property name="xaProperties">  
                <props>  
                    <prop key="url">${index.jdbc.url}</prop>  
                    <prop key="user">${index.jdbc.username}</prop>  
                    <prop key="password">${index.jdbc.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="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">  
            <property name="transactionManager">  
                <bean class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">  
                    <property name="forceShutdown" value="true"/>  
                </bean>  
            </property>  
            <property name="userTransaction">  
                <bean class="com.atomikos.icatch.jta.UserTransactionImp"/>  
            </property>  
        </bean> 
    
    
    
        <tx:annotation-driven/>
    
        <bean id="indexJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="k12_index_dataSource" />
        </bean>
    
    </beans>

    spring-merch-orm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:c="http://www.springframework.org/schema/c"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
        default-lazy-init="false">
    
        <context:annotation-config />
    
        <context:property-placeholder location="classpath*:/**/*.properties"
            ignore-unresolvable="true" />
    
        <context:component-scan base-package="fbs.demo">
            <context:exclude-filter type="annotation"
                expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
        
         <bean id="k12_merch_dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">  
            <property name="uniqueResourceName" value="ds2"/>  
            <property name="xaDataSourceClassName" value="${merch.jdbc.driverClassName}"/>  
            <property name="xaProperties">  
                <props>  
                    <prop key="url">${merch.jdbc.url}</prop>  
                    <prop key="user">${merch.jdbc.username}</prop>  
                    <prop key="password">${merch.jdbc.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="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">  
            <property name="transactionManager">  
                <bean class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">  
                    <property name="forceShutdown" value="true"/>  
                </bean>  
            </property>  
            <property name="userTransaction">  
                <bean class="com.atomikos.icatch.jta.UserTransactionImp"/>  
            </property>  
        </bean>  
    
    
    
        <tx:annotation-driven />
    
        <bean id="merchJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="k12_merch_dataSource" />
        </bean>
    
    </beans>

    spring-user-orm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:c="http://www.springframework.org/schema/c"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
        default-lazy-init="false">
    
        <context:annotation-config />
    
        <context:property-placeholder location="classpath*:/**/*.properties"
            ignore-unresolvable="true" />
    
        <context:component-scan base-package="fbs.demo">
            <context:exclude-filter type="annotation"
                expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
    
        <bean id="k12_user_dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">  
            <property name="uniqueResourceName" value="ds3"/>  
            <property name="xaDataSourceClassName" value="${user.jdbc.driverClassName}"/>  
            <property name="xaProperties">  
                <props>  
                    <prop key="url">${user.jdbc.url}</prop>  
                    <prop key="user">${user.jdbc.username}</prop>  
                    <prop key="password">${user.jdbc.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="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">  
            <property name="transactionManager">  
                <bean class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">  
                    <property name="forceShutdown" value="true"/>  
                </bean>  
            </property>  
            <property name="userTransaction">  
                <bean class="com.atomikos.icatch.jta.UserTransactionImp"/>  
            </property>  
        </bean>  
    
        <tx:annotation-driven />
    
        <bean id="userJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="k12_user_dataSource" />
        </bean>
    
    </beans>

    spring-jms.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:amq="http://activemq.apache.org/schema/core"
        xmlns:jms="http://www.springframework.org/schema/jms"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.3.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
            http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd">
        <context:property-placeholder location="classpath*:/**/*.properties" />
        <jms:annotation-driven></jms:annotation-driven>
    
        <amq:connectionFactory id="amqConnectionFactory"
            brokerURL="${brokerURL}" useAsyncSend="true" />
    
        <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
        <bean id="connectionFactory"
            class="org.springframework.jms.connection.CachingConnectionFactory">
            <constructor-arg ref="amqConnectionFactory" />
            <property name="sessionCacheSize" value="10" />
            <property name="cacheConsumers" value="false"></property>
            <property name="cacheProducers" value="false"></property>
        </bean>
    
        <!-- 类型转换器 -->
        <bean id="messageConverter"
            class="org.springframework.jms.support.converter.SimpleMessageConverter" />
    
        <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
        <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
            <property name="connectionFactory" ref="connectionFactory" />
            <property name="messageConverter" ref="messageConverter" />
            <!-- 非pub/sub模型(发布/订阅),false即队列模式 ,true为发布/订阅模式 -->
            <property name="pubSubDomain" value="false" />
            <property name="explicitQosEnabled" value="true" />
            <!--发送模式,1:非持久化,2:持久化 -->
            <property name="deliveryMode" value="2"></property>
            <!--开启分布式事务 -->
            <property name="sessionTransacted" value="true" />
        </bean>
    
        <bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
            <property name="connectionFactory" ref="connectionFactory" />
            <property name="messageConverter" ref="messageConverter" />
            <!-- 非pub/sub模型(发布/订阅),false即队列模式 ,true为发布/订阅模式 -->
            <property name="pubSubDomain" value="true" />
            <property name="explicitQosEnabled" value="true" />
            <!--发送模式,1:非持久化,2:持久化 -->
            <property name="deliveryMode" value="2"></property>
            <!--开启分布式事务 -->
            <property name="sessionTransacted" value="true" />
        </bean>
    
        <!-- 商户订单同步到用户 -->
        <bean id="abc" class="org.apache.activemq.command.ActiveMQQueue">
            <constructor-arg>
                <value>abc</value>
            </constructor-arg>
        </bean>
        <!-- 消息接收监听器用于异步接收消息 -->
    <!--     <bean id="merch2UserListener" class="k12.fee.listener.queue.Merch2UserListener"></bean>
        <bean
            class="org.springframework.jms.listener.DefaultMessageListenerContainer">
            <property name="connectionFactory" ref="connectionFactory" />
            <property name="destination" ref="merch2UserQueue" />
            <property name="messageListener" ref="merch2UserListener" />
            <property name="concurrency" value="50-100" />
            <property name="sessionTransacted" value="true"></property>
        </bean> -->
        
    </beans>

    4:service层

    package fbs.demo.service;
    
    import javax.annotation.Resource;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.MapMessage;
    import javax.jms.Message;
    import javax.jms.Session;
    
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jms.core.JmsTemplate;
    import org.springframework.jms.core.MessageCreator;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.huiqu.common.tools.utils.CodeUtil;
    
    @Service
    public class FbsDemo1Service {
        @Resource
        private JdbcTemplate indexJdbcTemplate;
        @Resource
        private JdbcTemplate merchJdbcTemplate;
        @Resource
        private Destination abc;
        @Resource
        private JmsTemplate jmsQueueTemplate;
        
        @Transactional
        public boolean add() {
            String id1 = CodeUtil.getUUID();
            String id2 = "2121";
            String sql1="INSERT INTO tabindex0 (order_num, id_number, schools_id) VALUES (?,?,?)";
            String sql2="INSERT INTO k12_fee.testa (id, NAME) VALUES (?,?)";
            
            jmsQueueTemplate.send(abc, new MessageCreator() {
                // 以map形式发送,以map形式接收
                @Override
                public Message createMessage(Session session) throws JMSException {
                    MapMessage message = null;
                    
                        message = session.createMapMessage();
                        session.createObjectMessage();
                        message.setString("buyer_id", "11111111111111");
            
                    return message;
                }
    
            });
            
            
            merchJdbcTemplate.update(sql2,id2,"");
            indexJdbcTemplate.update(sql1, id1,"232",11);
            throw new RuntimeException("");
            //return true;
        }
    
    }

    做到以上几步就可以回滚了

    注:tomcat启动时出错

    在每一个项目中都指定atomikos的文件名称,修改jta.properties文件中的
    
    com.atomikos.icatch.console_file_name = rm.out
    com.atomikos.icatch.log_base_name = rmlog.log
    com.atomikos.icatch.log_base_dir = ${catalina.base}/logs 两个属性的值,保证每个项目的名称都不一样
  • 相关阅读:
    属性序列化自定义与字母表排序-JSON框架Jackson精解第3篇
    URL及日期等特殊数据格式处理-JSON框架Jackson精解第2篇
    JSON数据处理框架Jackson精解第一篇-序列化与反序列化核心用法
    开源项目-跨项目及操作系统的通用代码生成器,解放您的双手
    图解并发与并行-分别从CPU和线程的角度理解
    8成以上的java线程状态图都画错了,看看这个-图解java并发第二篇
    面霸告诉你这些技术面试的非技术性经验,让你的面试成功率显著提升
    List集合对象去重及按属性去重的8种方法-java基础总结系列第六篇
    图解进程线程、互斥锁与信号量-看完不懂你来打我
    总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇
  • 原文地址:https://www.cnblogs.com/feiyun126/p/9234820.html
Copyright © 2011-2022 走看看