使用spring+mybatis+atomikos+tomcat构建分布式事务

本文通过一个demo,介绍如何使用spring+mybatis+atomikos+tomcat构建在一个事务中涉及两个数据源的web应用。

demo功能:实现一个能成功提交和回滚的涉及两个数据库数据源的XA事务。

demo将实现:

1.一次性在两个数据库的两张表中各插入一条数据并提交。

2.一次性在两个数据库的两张表中各插入一条数据并回滚。

测试方式:restful web api

使用工具:

spring 4.1.1.RELEASE

mybatis 3.2.7

atomikos 3.7.0

tomcat 7

在mysql中建立两个schema,分别为dev和qa。并在里面分别建立一张名字表。

schema:dev

table:namaDev

id | nameDev

scheme:qa

table:nameQa

id  |  nameQa

对应的sql为

 1 CREATE SCHEMA `qa` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
 2 CREATE SCHEMA `dev` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
 3
 4  CREATE  TABLE `dev`.`nameDev` (
 5   `id` BIGINT NOT NULL AUTO_INCREMENT ,
 6   `nameDev` VARCHAR(45) NULL ,
 7   PRIMARY KEY (`id`) ,
 8   UNIQUE INDEX `id_UNIQUE` (`id` ASC) );
 9
10   CREATE  TABLE `qa`.`nameQa` (
11   `id` BIGINT NOT NULL AUTO_INCREMENT ,
12   `nameQa` VARCHAR(45) NULL ,
13   PRIMARY KEY (`id`) ,
14   UNIQUE INDEX `id_UNIQUE` (`id` ASC) );

代码分析:

本项目使用spring框架,因此首先配置相关bean

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3        xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
  4        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  5        xmlns:rabbit="http://www.springframework.org/schema/rabbit"
  6        xmlns:cache="http://www.springframework.org/schema/cache" xmlns:task="http://www.springframework.org/schema/task"
  7        xsi:schemaLocation="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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
  8        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
  9     <context:component-scan base-package="com.xy">
 10         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
 11     </context:component-scan>
 12     <context:property-placeholder location="classpath:context/database.properties"/>
 13     <tx:annotation-driven/>
 14
 15     <bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init"
 16           destroy-method="close" abstract="true">
 17         <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
 18         <property name="poolSize" value="10" />
 19         <property name="minPoolSize" value="10"/>
 20         <property name="maxPoolSize" value="30"/>
 21         <property name="borrowConnectionTimeout" value="60"/>
 22         <property name="reapTimeout" value="20"/>
 23         <!-- 最大空闲时间 -->
 24         <property name="maxIdleTime" value="60"/>
 25         <property name="maintenanceInterval" value="60"/>
 26         <property name="loginTimeout" value="60"/>
 27         <property name="testQuery">
 28             <value>select 1</value>
 29         </property>
 30     </bean>
 31
 32     <bean id="qadataSource" parent="abstractXADataSource">
 33         <!-- value只要两个数据源不同就行,随便取名 -->
 34         <property name="uniqueResourceName" value="mysql/sitestone1" />
 35         <property name="xaDataSourceClassName"
 36                   value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
 37         <property name="xaProperties">
 38             <props>
 39                 <prop key="URL">${qa.db.url}</prop>
 40                 <prop key="user">${qa.db.user}</prop>
 41                 <prop key="password">${qa.db.password}</prop>
 42                 <prop key="pinGlobalTxToPhysicalConnection">true</prop>
 43             </props>
 44         </property>
 45     </bean>
 46
 47     <bean id="devdataSource" parent="abstractXADataSource">
 48         <!-- value只要两个数据源不同就行,随便取名 -->
 49         <property name="uniqueResourceName" value="mysql/sitestone" />
 50         <property name="xaDataSourceClassName"
 51                   value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
 52         <property name="xaProperties">
 53             <props>
 54                 <prop key="URL">${dev.db.url}</prop>
 55                 <prop key="user">${dev.db.user}</prop>
 56                 <prop key="password">${dev.db.password}</prop>
 57                 <prop key="pinGlobalTxToPhysicalConnection">true</prop>
 58             </props>
 59         </property>
 60     </bean>
 61
 62
 63
 64     <bean id="qasqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
 65         <property name="dataSource" ref="qadataSource" />
 66         <property name="mapperLocations" value="classpath*:com/xy/dao/*.xml" />
 67     </bean>
 68
 69     <bean id="devsqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
 70         <property name="dataSource" ref="devdataSource" />
 71         <property name="mapperLocations" value="classpath*:com/xy/daodev/*.xml" />
 72     </bean>
 73
 74     <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
 75           init-method="init" destroy-method="close">
 76         <property name="forceShutdown">
 77             <value>true</value>
 78         </property>
 79     </bean>
 80     <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
 81         <property name="transactionTimeout" value="300" />
 82     </bean>
 83
 84     <bean id="transactionManager"
 85           class="org.springframework.transaction.jta.JtaTransactionManager">
 86         <property name="transactionManager">
 87             <ref bean="atomikosTransactionManager"/>
 88         </property>
 89         <property name="userTransaction">
 90             <ref bean="atomikosUserTransaction"/>
 91         </property>
 92         <!-- 必须设置,否则程序出现异常 JtaTransactionManager does not support custom isolation levels by default -->
 93         <property name="allowCustomIsolationLevels" value="true"/>
 94
 95     </bean>
 96
 97
 98
 99     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
100         <property name="basePackage" value="com.xy.dao"/>
101         <property name="sqlSessionFactoryBeanName" value="qasqlSessionFactory" />
102     </bean>
103
104     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
105         <property name="basePackage" value="com.xy.daodev"/>
106         <property name="sqlSessionFactoryBeanName" value="devsqlSessionFactory" />
107     </bean>
108 </beans>

其中qadataSource和devdataSource是对应两个数据库的数据源,qasqlSessionFactory和devsqlSessionFactory是mybatis的sessionfactory,两个MapperScannerConfigurer自动将不同数据源的sql语句文件与interface自动装配起来,atomikosTransactionManager会自动管理两个atomikos的数据源的事务,即resource manager,atomikosUserTransaction为最上层的事务管理器为transaction manager。(关于RM和TM,请参见上篇博文)。

Model类如下:package com.xy.model

 1 package com.xy.model;
 2
 3 /**
 4  * Created by yun.xia on 2015/1/30.
 5  */
 6 public class NameQa {
 7     private long id;
 8     private String nameQa;
 9
10     public long getId() {
11         return id;
12     }
13
14     public void setId(long id) {
15         this.id = id;
16     }
17
18     public String getNameQa() {
19         return nameQa;
20     }
21
22     public void setNameQa(String nameQa) {
23         this.nameQa = nameQa;
24     }
25 }

nameQa class

qa数据源的mybatis的Mapper接口为:package com.xy.dao

1 package com.xy.dao;
2
3 import com.xy.model.NameQa;
4
5 public interface NameQaMapper {
6     int insert(NameQa nameQa);
7 }

NameQaMapper

时间: 2024-10-13 09:28:06

使用spring+mybatis+atomikos+tomcat构建分布式事务的相关文章

使用spring+hibernate+atomikos+tomcat构建分布式事务

本文通过一个demo,介绍如何使用spring+hibernate+atomikos+tomcat构建在一个事务中涉及两个数据源的web应用. demo功能:实现一个能成功提交和回滚的涉及两个数据库数据源的XA事务. demo将实现: 1.一次性在两个数据库的两张表中各插入一条数据并提交. 2.一次性在两个数据库的两张表中各插入一条数据并回滚. 测试方式:restful web api 使用工具: spring 4.1.1.RELEASE hibernate 4.2.4.Final atomik

基于spring+mybatis+atomikos+jta实现分布式事务(2)-动态切换数据源

本文介绍基于spring+mybatis+atomikos+jta实现分布式事务,由程序动态切换数据源,通过atomikos可实现分布式事务一致性. 版本:spring-3.2.9.RELEASE.mybatis-3.4.4.atomikos-4.0.5.jdk1.8 1,maven配置文件pom.xml如下: <!-- test --> <dependency> <groupId>junit</groupId> <artifactId>juni

spring+mybatis+Atomikos JTA事务配置说明

一.概览 Atomikos是一个公司名字,旗下最著名的莫过于其Atomikos的事务管理器产品.产品分两个:一个是开源的TransactionEssentials,一个是商业的ExtremeTransactions. TransactionEssentials的主要特征: JTA/XA 事务管理 -- 提供事务管理和连接池 不需要应用服务器 -- TransactionEssentials可以在任何Java EE应用服务器中运行,也就是不依赖于任何应用服务器 开源 -- TransactionE

使用Atomikos实现JTA分布式事务

使用Atomikos实现JTA分布式事务 在这篇文章中: 1.1 JTA事务模型 2 JTA规范接口 3 Atomikos分布式事务 本文全面的介绍了JTA分布式事务模型和接口规范,以及开源的分布式事务解决方案Atomikos.笔者认同"talk is cheap,show me the code",因此在文章最后,给出一个完整的Atomikos与spring.mybatis整合的完整案例. 1 JTA规范 Java事务API(JTA:Java Transaction API)和它的同

springmvc+spring+mybatis+maven项目构建

1.首先在myeclipse10中安装maven的插件,将插件放入D:\Program Files (x86)\myEclipse10\MyEclipse Blue Edition 10\dropins\maven中, 2. 新建文件:maven.link填入如下内容:path=D:/Program Files (x86)/myEclipse10/MyEclipse Blue Edition 10/dropins/maven 3.重启myeclipse插件安装成功. 4.在myeclipse10

Spring Cloud Alibaba | 微服务分布式事务之Seata

Spring Cloud Alibaba | 微服务分布式事务之Seata 本篇实战所使用Spring有关版本: SpringBoot:2.1.7.RELEASE Spring Cloud:Greenwich.SR2 Spring CLoud Alibaba:2.1.0.RELEASE 1. 概述 在构建微服务的过程中,不管是使用什么框架.组件来构建,都绕不开一个问题,跨服务的业务操作如何保持数据一致性. 2. 什么是分布式事务? 首先,设想一个传统的单体应用,无论多少内部调用,最后终归是在同一

spring + myBatis 常见错误:注解事务不回滚

最近项目在用springMVC+spring+myBatis框架,在配置事务的时候发现一个事务不能回滚的问题. 刚开始配置如下:springMVC.xml配置内容: spring.xml配置内容 从上面两个配置文件看出,开始的时候我把Service配置在springMVC中的.但是,事务注解我配置在了spring中.这样就会出现问题了.因为spring的容器(applicationContext)和springMVC的(applicationContext)是不同的. spring容器加载得时候

Spring事务隔离级别与传播机制,spring+mybatis+atomikos实现分布式事务管理

本文转载于本人另一博客[http://blog.csdn.net/liaohaojian/article/details/68488150] 1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做: 一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是应该处于正确

spring事务隔离级别、传播行为以及spring+mybatis+atomikos实现分布式事务管理

转载自:http://blog.csdn.net/liaohaojian/article/details/68488150 1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做: 一致性(Consistency):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是应该处于正确的状态,即数据完整