(附源码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/testspring.datasource.primary.username=rootspring.datasource.primary.password=rootspring.datasource.primary.driver-class-name=com.mysql.jdbc.Driverspring.datasource.primary.xa-data-source-class-name=com.alibaba.druid.pool.xa.DruidXADataSource #数据源二spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test1spring.datasource.secondary.username=rootspring.datasource.secondary.password=rootspring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driverspring.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"));//扫描指定目录的xmlreturn 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"));//扫描指定目录的xmlreturn 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
转载于:https://www.cnblogs.com/qq1141100952com/p/11548257.html
(附源码gitHub下载地址)spring boot -jta-atomikos分布式事务相关推荐
- 仿蘑菇街,京东,苏宁易购,海尔商城等33套大气购物商城网站模板,附源码免费下载地址...
来源 | web前端开发 在很早之前,跟大家分享过很多有关于网站模板的素材资源,有企业网站,也有购物商城,还有后台管理模板,以及大数据页面模板等等. 今天我们再跟大家分享32套商城网站源码,有的是比较 ...
- (附源码)小程序+spring boot校园二手交易平台 毕业设计 191637
Springboot校园二手交易平台小程序 摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最 ...
- 173个Android项目源码及下载地址
173个Android项目源码及下载地址 注:最近一直没有上CSDN,看到不少想学Android的朋友们想要这几个Android项目源码,所以我把它上传到了CSDN,希望能在Android的学习路上对 ...
- 资源:代码舞动动画 提供gif图片(含程序、源码、下载地址)
资源:代码舞动动画 提供gif图片(含程序.源码.下载地址) 案例 · 教程 · 地址: 3行代码 为你的网站博客添加萌萌哒可爱二次元女动漫玩偶人物(看板娘) 抖音上爆红的美女动态代码图如何实现? 以 ...
- 【源码阅读】看Spring Boot如何自动装配ActiveMQ收发组件
源于好奇,我研究了一下Spring Boot中ActiveMQ相关组件是如何自动装配的.记录如下. 源码路径 本文以Spring Boot 1.5.10.RELEASE版本为例. 在spring-bo ...
- 微信小程序UI自动化实践:python+minium+PO模式(超详细教程附源码供下载)
文章目录 前言 一.minium介绍 二.安装环境 1. 安装minium doc 2. 安装minium 3. 启动小程序 三.准备知识 1. 启动 2. 配置 3. 命令行运行 4. 元素定位 5 ...
- wpf 模拟抖音很火的罗盘时钟,附源码,下载就能跑
wpf 模拟抖音很火的罗盘时钟,附源码 前端时间突然发现,抖音火了个壁纸,就是黑底蕾丝~~~ 错错错,黑底白字的罗盘时钟! 作为程序员的我,也觉得很新颖,所以想空了研究下,这不,空下来了就用wpf, ...
- Django项目实战(附源码免费下载)
制作图书管理系统(末尾附源码) 第一步先更改settings.py里面的必要配置,更改或附件项如下 INSTALLED_APPS = ['django.contrib.admin','django.c ...
- 【绝对给力】Android开发免豆资料(教程+工具+源码)下载地址汇总 【转载自51CTO】
下载中心特意为广大搞android开发的同学整理了一批0下载豆的资料,希望大家喜欢~ 资料目录下载:http://down.51cto.com/data/439071 目录内容无格式浏览: 教程下载: ...
最新文章
- MXNET源码中NDArray数据的获取和打印
- R语言对数线性模型loglm函数_使用R语言进行混合线性模型(mixed linear model) 分析代码及详解...
- python 获取 文件修改时间 距离 当前时间 天数 秒数
- 设置图例字体_plotly_标题参数详解(大小,颜色,字体,位置)
- 用fgets替代gets
- Serverless Devs 的官网是如何通过 Serverless Devs 部署的
- 电力电子应用技术_RFID技术应用在电力行业工具管控
- CentOS7安装Docker与使用篇
- log4net异步写入日志_微信支付万亿日志在Hermes中的实践
- C++中的临时对象都是const类型
- python与环境统计学--两样本均值的差异显著性检验之z检验,t检验和对应例题代码展示(一)
- Maven配置pom引入本地依赖
- 如何实现微信和淘宝的扫码登录
- 基金从业-证券投资基金概述第二章重点(了解投资,做好程序员下半生规划)
- 弄错了会很尴尬的英文
- Selenium.Chrome相关配置及用法
- 虚幻引擎 虚拟直播,实时渲染直播画面
- LaTeX学习总结5(插图)
- 大数据-Zookeeper:对大数据平台中的各个模块进行集中配置和调度【原理与搭建】
- Windows WSL安装GNU Radio
热门文章
- VScode 开发stm32无法识别uint32_t,uint16_t,uint8_t问题
- python安装虚拟环境出现错误_virtualenv 安装虚拟环境问题 请大神指点一二
- React中的受控组件和非受控组件
- LeetCode 1971. Find if Path Exists in Graph(图的遍历)
- LeetCode 1742. 盒子中小球的最大数量
- LeetCode 1726. 同积元组(排列组合)
- LeetCode 329. 矩阵中的最长递增路径(记忆化递归)
- LeetCode 1065. 字符串的索引对
- LeetCode 454. 四数相加 II(哈希)
- 数据结构--散列表 Hash Table