(附源码gitHub下载地址)spring boot -jta-atomikos分布式事务
应用场景:双数据源,就是某些项目会涉及到两个数据源或者两个以上的数据源,这个多数据源的项目一般是数据同步,也就是把数据从另一个系统中,保存到另一个系统,两边的 数据库又不一样,比如一个Mysql、一个Sql Server。但是不管是什么类型的数据库,我们都不管,直接连接就是。
为什么要使用分布式事务:顾名思义,事务就是回滚,比如如果一个在保存数据的时候,在A数据库已经 保存,但是在保存数据在B的过程抛出异常,那么是不是应该全部回滚,把已经 保存了的A、B数据库的数据全部回滚?答案是确定的。下面就解说:
pom.xml主要依赖:
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
properties配置文件:
#数据源一
spring.datasource.primary.url=jdbc:mysql://localhost:3306/test
spring.datasource.primary.username=root
spring.datasource.primary.password=root
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.primary.xa-data-source-class-name=com.alibaba.druid.pool.xa.DruidXADataSource
#数据源二
spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test1
spring.datasource.secondary.username=root
spring.datasource.secondary.password=root
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.secondary.xa-data-source-class-name=com.alibaba.druid.pool.xa.DruidXADataSource
数据源的配置类:DataSourceConfig.class
import com.alibaba.druid.pool.xa.DruidXADataSource; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; @Configuration
public class DataSourceConfig {
//这里一定要加主数据源的注解
@Primary
@Bean(name = "primaryProperty")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DruidXADataSource primaryDataSource() {
return new DruidXADataSource();
}
//这里是第二个数据源
@Bean(name = "secondaryProperty")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DruidXADataSource secondaryDataSource() {
return new DruidXADataSource();
}
}
再分别配置他们的数据源:以便包扫描、事务交给jta-atomikos统一管理
主数据源配置类:
import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.atomikos.jdbc.AtomikosDataSourceBean; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; import javax.sql.DataSource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import tk.mybatis.spring.annotation.MapperScan; @Configuration
@MapperScan(basePackages = {"com.example.dao.primary"}, sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class PrimaryDBConfig { @Bean(name = "primaryDataSource")
public DataSource dataSourceCar(@Qualifier("primaryProperty") DruidXADataSource druidXADataSource) {
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(druidXADataSource);
xaDataSource.setUniqueResourceName("primaryDataSource");
return xaDataSource;
} @Bean(name = "primarySqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/primary/*Mapper.xml"));//扫描指定目录的xml
return bean.getObject();
} @Bean(name = "primarySqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
同理,第二个数据源的配置SecondaryDBConfig.java
@Configuration
@MapperScan(basePackages = {"com.example.dao.secondary"}, sqlSessionTemplateRef = "secondarySqlSessionTemplate")
public class SecondaryDBConfig { @Bean(name = "secondaryDataSource")
public DataSource dataSourceCar(@Qualifier("secondaryProperty") DruidXADataSource druidXADataSource) {
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(druidXADataSource);
xaDataSource.setUniqueResourceName("secondaryDataSource");
return xaDataSource;
} @Bean(name = "secondarySqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/secondary/*Mapper.xml"));//扫描指定目录的xml
return bean.getObject();
} @Bean(name = "secondarySqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("secondarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
最后我们还需要配置事务管理的配置类:TransactionManagerConfig.java,以便把数据源一,数据源二全部交给jta-atomikos管理,实现分布式事务管理:
import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.jta.JtaTransactionManager; import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction; @Configuration
public class TransactionManagerConfig { @Bean(name = "userTransaction")
public UserTransaction userTransaction() throws Throwable {
UserTransactionImp userTransactionImp = new UserTransactionImp();
userTransactionImp.setTransactionTimeout(10000);
return userTransactionImp;
} @Bean(name = "atomikosTransactionManager")
public TransactionManager atomikosTransactionManager() throws Throwable {
UserTransactionManager userTransactionManager = new UserTransactionManager();
userTransactionManager.setForceShutdown(false);
return userTransactionManager;
} @Bean(name = "transactionManager")
@DependsOn({ "userTransaction", "atomikosTransactionManager" })
public PlatformTransactionManager transactionManager() throws Throwable {
return new JtaTransactionManager(userTransaction(),atomikosTransactionManager());
}
}
最后我们在service类上加上注解:@Transactional(value = "transactionManager", rollbackFor = Exception.class)
当value = "transactionManager",则是分布式事务的管理。至此,全部完成。
gitHub完整项目下载地址:https://gitee.com/qhThomas/springboot-mybatis-duria.git
(附源码gitHub下载地址)spring boot -jta-atomikos分布式事务的更多相关文章
- CentOS6.6系统源代码安装mysql5.5.28教程(附源码包下载地址)+sysbench的安装
mysql从5.5版本开始,不再使用./configure编译,而是使用cmake编译器,具体的cmake编译参数可以参考mysql官网文档(※ 非常重要) http://dev.mysql.com/ ...
- wpf 模拟抖音很火的罗盘时钟,附源码,下载就能跑
wpf 模拟抖音很火的罗盘时钟,附源码 前端时间突然发现,抖音火了个壁纸,就是黑底蕾丝~~~ 错错错,黑底白字的罗盘时钟! 作为程序员的我,也觉得很新颖,所以想空了研究下,这不,空下来了就用wpf, ...
- spring framework项目源码github托管地址
方法一:直接下载,github托管地址:http://repo.spring.io/simple/libs-release-local/org/springframework/spring/ 方法二: ...
- Spring Boot自动配置源码解析(基于Spring Boot 2.0.2.RELEASE)
在Spring Boot官方介绍中,首一段话是这样的(如下图).我们可以大概了解到其所表达的含义:我们可以利用Spring Boot写很少的配置来创建一个非常方便的基于Spring整合第三方类库的单体 ...
- Mybatis入门(附源码压缩包下载)
首先,来个项目全景预览,文章尾部附上Demo下载链接 [1]pom.xml配置(加入jar包) <project xmlns="http://maven.apache.org/POM/ ...
- [小工具] Command-line CPU Killer(附源码及下载链接)
博主有次在拆卸自己的笔记本电脑后,发现电脑如果静置时间长了有时会重启,但奇怪的是当我自己在电脑前工作的时候从来没有重启过.据此推测可能 CPU 完全空闲的时候风扇完全停转了,虽然 CPU 温度不高,但 ...
- mysql php nginx 源码包下载地址
http://mirror.cogentco.com/pub/mysql/MySQL-5.5/ http://mirrors.sohu.com/php/ http://nginx.org/downlo ...
- hadoop源码svn下载地址
1.apache开源框架
- Android 高仿 频道管理----网易、今日头条、腾讯视频 (可以拖动的GridView)附源码DEMO
距离上次发布(android高仿系列)今日头条 --新闻阅读器 (二) 相关的内容已经半个月了,最近利用空闲时间,把今日头条客户端完善了下.完善的功能一个一个全部实现后,就放整个源码.开发的进度就是按 ...
随机推荐
- golang学习(1)---快速hello world
很多著名的计算机语言都是一两个人在业余时间捣鼓出来的,但是Go语言是由Google的团队打造的.可能一些基础的知识点我不会细讲,因为这个时代你真的得快速学习,才能适应发展. 来看看go的hello, ...
- Oracle 主键、联合主键的查询与创建
--查询某个表是否有唯一主键 select cu.* from user_cons_columns cu, user_constraints au where cu.constraint_name = ...
- Spring Boot 统一异常这样处理和剖析,安否?
话说异常 「欲渡黄河冰塞川,将登太行雪满天」,无论生活还是计算机世界难免发生异常,上一篇文章RESTful API 返回统一JSON数据格式 说明了统一返回的处理,这是请求一切正常的情形:这篇文章将说 ...
- JavaScript的垃圾回收机制与内存泄漏
常用的两种算法: 引用计数(新版浏览器已弃用,弃用原因:会出现循环引用的情况,无法进行垃圾回收,导致内存泄漏) 标记清除 引用计数法 引用计数,顾名思义一个对象是否有指向它的引用,即看栈中是否有指向要 ...
- 在linux系统中配置NVMe over TCP
1. 准备环境 1.1 准备linux系统 要求的linux系统可以是运行在物理机上,也可以是虚拟机上: 建议有个linux系统,一个做host,一个做target,如果资源紧张也可以把host和ta ...
- Vim高手,从来不用鼠标
Vim脱离鼠标第一步 平时不可缺少的会用到vim,但是避免不了鼠标,事实上,省略鼠标是完全可以的,没有想像中那么难,看我短短几行带大家一起省略鼠标. 对了,vim有三种模式,基本模式就是用来输入命令的 ...
- python+unittest框架第六天unittest之优化测试报告
今天的内容主要是,用第三方的HTMLRUNner 第三方的报告来优化之前第五天批量执行案例的测试报告.案例的部分看第五天的批量执行笔记~ HTMLRUNner他可以生成更美观的测试报告,基于前辈造的车 ...
- python学习——高阶函数
递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.使用递归函数的优点是逻辑简单清晰,缺点就是过深的调用会导致栈溢出.但是针对尾递归优化的语言可以通过尾递归防 ...
- 设计模式(C#)——02简单工厂模式
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来.通俗来说,你只关心怎么用,不用关心怎么做 ...
- unity之初级工程师
一.值类型与引用类型 值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中.值类型变量声明后,不管是否已经赋值,编译器为其分配内存.值类型的实例通常是在线程栈上分配的(静态 ...