一、前言

       springboot整合多数据源解决分布式事务。

            1.多数据源采用分包策略 

            2.全局分布式事务管理:jta-atomikos。

       在此记录下,分享给大家。

二、springboot整合多数据源解决分布式事务

1、pom文件 依赖引入

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.1.8.RELEASE</version>

<relativePath />

</parent>

<dependencies>

<!-- SpringBoot 测试 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

<!-- SpringBoot web组件 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!-- mybatis 支持 SpringBoot -->

<dependency>

<groupId>org.mybatis.spring.boot</groupId>

<artifactId>mybatis-spring-boot-starter</artifactId>

<version>1.1.1</version>

</dependency>

<!-- mysql 驱动 -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.38</version>

</dependency>

<!-- 全局事务集中管理解决分布式事务 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-jta-atomikos</artifactId>

</dependency>

<!-- SpringBoot 自动配置 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-configuration-processor</artifactId>

<optional>true</optional>

</dependency>

<!-- 注解式插入/构建/优雅代码 -->

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<version>1.18.4</version>

</dependency>

</dependencies>

2 application.yml 新增配置

spring:

datasource:

## 用户数据库

user:

url: jdbc:mysql://127.0.0.1:3306/yys_user

username: root

password: 123456

borrowConnectionTimeout: 30

loginTimeout: 30

maintenanceInterval: 60

maxIdleTime: 60

maxLifetime: 20000

maxPoolSize: 25

minPoolSize: 3

uniqueResourceName:
userDataSource

testQuery: select 1

## 订单数据库

order:

url: jdbc:mysql://127.0.0.1:3306/yys_order

username: root

password: 123456

borrowConnectionTimeout: 30

loginTimeout: 30

maintenanceInterval: 60

maxIdleTime: 60

maxLifeTime: 20000

maxPoolSize: 25

minPoolSize: 3

uniqueResourceName:
orderDataSource

testQuery: select 1

3userConfig.java

@ConfigurationProperties(prefix = "spring.datasource.user")

@Data

public class UserConfig {

private String url;

private String userName;

private String password;

private int
minPoolSize;

private int
maxPoolSize;

private int
maxLifeTime;

private int
maxIdleTime;

private int
loginTimeout;

private int
maintenanceInterval;

private int borrowConnectionTimeout;

private String testQuery;

private String
uniqueResourceName;

}

4userDataSourceConfig.java

/**

 * 用户数据源

 *      Config

 * @author yys

 */

@Configuration

@MapperScan(basePackages = "com.yys.user.mapper", sqlSessionTemplateRef
= "userSqlSessionTemplate")

public class UserDataSourceConfig {

/**

     * 创建 XADataSource

     * @return

     */

@Bean("userDataSource")

public DataSource userDataSource(UserConfig
userConfig) throws SQLException {

// 1、创建Mysql XADataSource

MysqlXADataSource
mysqlXaDataSource = new MysqlXADataSource();

mysqlXaDataSource.setUrl(userConfig.getUrl());

mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

mysqlXaDataSource.setPassword(userConfig.getPassword());

mysqlXaDataSource.setUser(userConfig.getUserName());

mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

// 2、将本地事务注册到 Atomikos 全局事务

AtomikosDataSourceBean
xaDataSource = new AtomikosDataSourceBean();

xaDataSource.setXaDataSource(mysqlXaDataSource);

xaDataSource.setUniqueResourceName(userConfig.getUniqueResourceName());

xaDataSource.setMinPoolSize(userConfig.getMinPoolSize());

xaDataSource.setMaxPoolSize(userConfig.getMaxPoolSize());

xaDataSource.setMaxLifetime(userConfig.getMaxLifeTime());

xaDataSource.setBorrowConnectionTimeout(userConfig.getBorrowConnectionTimeout());

xaDataSource.setLoginTimeout(userConfig.getLoginTimeout());

xaDataSource.setMaintenanceInterval(userConfig.getMaintenanceInterval());

xaDataSource.setMaxIdleTime(userConfig.getMaxIdleTime());

xaDataSource.setTestQuery(userConfig.getTestQuery());

return xaDataSource;

}

/**

     * 创建 SQL会话工厂

     * @param dataSource

     * @return

     * @throws Exception

     */

@Bean("userSqlSessionFactory")

public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource
dataSource) throws Exception {

SqlSessionFactoryBean
sqlSessionFactoryBean = new SqlSessionFactoryBean();

sqlSessionFactoryBean.setDataSource(dataSource);

return
sqlSessionFactoryBean.getObject();

}

/**

     * 创建用户 SqlSession模板

     * @param sqlSessionFactory

     * @return

     */

@Bean("userSqlSessionTemplate")

public SqlSessionTemplate
userSqlSessionTemplate(@Qualifier("userSqlSessionFactory")
SqlSessionFactory sqlSessionFactory) {

return new
SqlSessionTemplate(sqlSessionFactory);

}

}

5orderConfig.java

@ConfigurationProperties(prefix = "spring.datasource.order")

@Data

public class OrderConfig {

private String url;

private String userName;

private String password;

private int minPoolSize;

private int
maxPoolSize;

private int
maxLifeTime;

private int
maxIdleTime;

private int
loginTimeout;

private int
maintenanceInterval;

private int
borrowConnectionTimeout;

private String testQuery;

private String
uniqueResourceName;

}

6orderDataSourceConfig.java

/**

 * 订单数据源

 *      Config

 * @author yys

 */

@Configuration

@MapperScan(basePackages = "com.yys.order.mapper",
sqlSessionTemplateRef = "orderSqlSessionTemplate")

public class OrderDataSourceConfig {

/**

     * 创建 XADataSource

     * @return

     */

@Bean("orderDataSource")

public DataSource orderDataSource(OrderConfig
orderConfig) throws SQLException {

// 1、创建Mysql XADataSource

MysqlXADataSource
mysqlXaDataSource = new MysqlXADataSource();

mysqlXaDataSource.setUrl(orderConfig.getUrl());

mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

mysqlXaDataSource.setPassword(orderConfig.getPassword());

mysqlXaDataSource.setUser(orderConfig.getUserName());

mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);

// 2、将本地事务注册到 Atomikos 全局事务

AtomikosDataSourceBean xaDataSource
= new AtomikosDataSourceBean();

xaDataSource.setXaDataSource(mysqlXaDataSource);

xaDataSource.setUniqueResourceName(orderConfig.getUniqueResourceName());

xaDataSource.setMinPoolSize(orderConfig.getMinPoolSize());

xaDataSource.setMaxPoolSize(orderConfig.getMaxPoolSize());

xaDataSource.setMaxLifetime(orderConfig.getMaxLifeTime());

xaDataSource.setBorrowConnectionTimeout(orderConfig.getBorrowConnectionTimeout());

xaDataSource.setLoginTimeout(orderConfig.getLoginTimeout());

xaDataSource.setMaintenanceInterval(orderConfig.getMaintenanceInterval());

xaDataSource.setMaxIdleTime(orderConfig.getMaxIdleTime());

xaDataSource.setTestQuery(orderConfig.getTestQuery());

return xaDataSource;

}

/**

     * 创建 SQL会话工厂

     * @param dataSource

     * @return

     * @throws Exception

     */

@Bean("orderSqlSessionFactory")

public SqlSessionFactory orderSqlSessionFactory(@Qualifier("orderDataSource") DataSource
dataSource) throws Exception {

SqlSessionFactoryBean
sqlSessionFactoryBean = new SqlSessionFactoryBean();

sqlSessionFactoryBean.setDataSource(dataSource);

return sqlSessionFactoryBean.getObject();

}

/**

     * 创建订单 SqlSession模板

     * @param
sqlSessionFactory

     * @return

     */

@Bean("orderSqlSessionTemplate")

public SqlSessionTemplate
orderSqlSessionTemplate(@Qualifier("orderSqlSessionFactory")
SqlSessionFactory sqlSessionFactory) {

return new
SqlSessionTemplate(sqlSessionFactory);

}

}

UserService.java

public class UserService {

@Autowired

private UserMapper
userMapper;

@Autowired

private OrderMapper
orderMapper;

// 全局事务处理器

// 事务底层原理采用aop技术做增强

// 无需再指定某个事务管理器,全交给 Atomikos 全局事务

@Transactional

public Boolean addUser(String name,
Integer age, Double amount, String address) {

// 操作用户库

int i =
userMapper.addUser(name, age);

// 操作订单库

int j =
orderMapper.addOrder(amount, address);

// 测试事务回滚(age = 0:回滚;age > 0:事务提交)

int flag = 1 / age;

return i > 0 && j
> 0;

}

}

springboot整合多数据源解决分布式事务

springboot整合多数据源解决分布式事务的更多相关文章

  1. RabbitMQ解决分布式事务

    案例:经典案例,以目前流行点外卖的案例,用户下单后,调用订单服务,让后订单服务调用派单系统通知送外卖人员送单,这时候订单系统与派单系统采用MQ异步通讯. RabbitMQ解决分布式事务原理: 采用最终 ...

  2. 3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务

    文章来自: https://blog.csdn.net/qq_29242877/article/details/79033287 在一些复杂的应用开发中,一个应用可能会涉及到连接多个数据源,所谓多数据 ...

  3. 【分布式事务】使用atomikos+jta解决分布式事务问题

    一.前言 分布式事务,这个问题困惑了小编很久,在3个月之前,就间断性的研究分布式事务.从MQ方面,数据库事务方面,jta方面.近期终于成功了,使用JTA解决了分布式事务问题.先写一下心得,后面的二级提 ...

  4. LCN解决分布式事务原理解析+项目实战(原创精华版)

    写在前面: 原创不易,如果觉得不错推荐一下,谢谢! 由于工作需要,公司的微服务项目需解决分布式事务的问题,且由我进行分布式事务框架搭建和整合工作. 那么借此机会好好的将解决分布式事务的内容进行整理一下 ...

  5. 使用kafka消息队列解决分布式事务(可靠消息最终一致性方案-本地消息服务)

    微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务 本文转自:http://skaka.me/blog/2016/04/21/springcloud1/ 不同于单一 ...

  6. SpringBoot整合Mybatis,并实现事务控制

    SpringBoot整合Mybatis,并实现事务控制 1. 在pom文件里添加相关maven文件 <parent> <groupId>org.springframework. ...

  7. 二、springboot项目使用seata实现分布式事务

    所有文章 https://www.cnblogs.com/lay2017/p/12078232.html 正文 在上一篇文章中,我们简单地了解了一下什么是seata.它是来自阿里巴巴的内部项目不断地发 ...

  8. springBoot整合多数据源

    springBoot整合相关 1:springBoot整合多数据源: 应用场景:     项目需要同时连接两个不同的数据库A, B,并且它们都为主从架构,一台写库,多台读库. 工具/版本: jdk1. ...

  9. 搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务

    搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 初步认识RocketMQ的核心模块 rocketmq模块 rocketmq-broker:接受生产者发来的消息并存储(通过调用rocke ...

随机推荐

  1. ARTS起始篇

    ARTS简要说明(每周需要完成以下四项): Algorithm:每周至少做一道 leetcode 的算法题,编程训练.刻意练习. Review:需要阅读并点评至少一篇英文技术文章,这个是四项里面对我最 ...

  2. cut和grep 选取命令

    cut命令 cut:将一段信息的某一段"切"出来,处理的信息是以行为单位.参数: -d :后接分隔字符,与-f一起使用: -f :依据-d的分隔字符将一段信息切割成为数段,用-f取 ...

  3. Charles使用笔记001

    一.抓电脑的请求 Proxy-->勾选Windows Proxy 二.Charles 拦截原理 三.Charles 拦截修改数据 选择一个链接-->右键-->勾选Breakpoint ...

  4. SHELL 变量一

    SHELL变量分为三类:本地变量.环境变量和位置参数 变量存在三种基本结构:变量名.操作符(个人定义).变量值 比如:var=blue 变量名:var 操作符:= 变量值:blue 变量的设置规则: ...

  5. 入门 - SpringBoot 2.x 使用 JWT

    JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理和用法 一.跨域认证遇到的问题 由于多终端的出现,很多的站点通过 web api restful 的形式对外 ...

  6. 在HTML中使用JavaScript(浏览器对js的加载机制分析)

    前言: 向HTML页面中插入JavaScrip的主要方法,就是使用<script>标签.主要探讨<script>标签的在HTML页面的渲染机制.对应的业务场景:从js的加载机制 ...

  7. Oracle19c 如何用rman duplicate 克隆一个数据库。(Active方式)

    Oracle19c 如何用rman duplicate 克隆一个数据库. 首先克隆有两种方法,一种是Backup-Based,一种是Active方式.官网文档链接https://docs.oracle ...

  8. VUP虚拟直播与光学动作捕捉技术

    虚拟直播将虚拟场景.虚拟形象实时显示在观众面前,虚拟场景与人物替代了原有的耗费较大搭建成本的实景场景与真人出镜,为观众带来全新的视觉体验,同时新技术降低了原有场景搭建成本,是近些年继AI.VR.动作捕 ...

  9. ThreadLocal(十一)

    一.ThreadLocal源码剖析 ThreadLocal源码剖析 ThreadLocal其实比较简单,因为类里就三个public方法:set(T value).get().remove().先剖析源 ...

  10. CSS样式实现表头和列固定

    效果图:第一行和第一列固定       <!DOCTYPE html> <html lang="zh"> <head> <meta cha ...