一、前言

       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. 团队nabcd(校园大事件)

    我们团队项目名称是TD校园通,作为辅助功能校园大事件,一样是一个亮眼的功能. 我们的大事件功能主要解决了大家qq微信群聊过多,信息杂,很多时候错过了校园内的大事件,错失了好的活动的痛苦. 我们计划在主 ...

  2. 在SublimeText3中搭建Verilog开发环境记录(一)

    ------------恢复内容开始------------ ------------恢复内容开始------------ ## 前言 *工欲善其事,必先利其器* 一款好用的撸码软件,能够大大的提高工 ...

  3. Shiro精通学习——【第一集:入门】

    入门: main方法直接执行:https://blog.csdn.net/a907691592/article/details/80559904 使用配置文件方式:https://blog.csdn. ...

  4. sql-3-DML_DQL

    DML-操作数据 1.insert语句 --增加一行数据 insert into 表名([字段1,字段2,字段3,...])values('值1','值2','值3',...); insert int ...

  5. nacos Connection refused (Connection refused)

    记录一次"异常bug",具体信息如下.主要是记录一下处理过程,可能口水话比较多,如果想看结果,直接往后拉即可. 最后一行 起初,运维同事找到我,跟我说程序出问题了,系统升级,一直连 ...

  6. Spring常见问题(五)

    1.静态资源访问配置 绝对路径:访问静态资源. <mvc:resources location="/js/" mapping="/js/**">&l ...

  7. UnitTest 用法

    功能 1.能组织多个用例去执行 2.提供丰富的断言方法 3.提供丰富的日志与测试结果 核心要素 1.TestCase 2.TestSuite 3.TextTestRunner 4.Fixture 用法 ...

  8. 用 5W1H 告诉你如何规划合理的测试策略

    ​​摘要:测试策略描述了测试工程的总体方法和目标.描述目前在进行哪一阶段的测试以及每个阶段内在进行的测试种类(功能测试.性能测试.覆盖测试等)以及测试人力安排等. 本文分享自华为云社区<浅谈敏捷 ...

  9. 论文笔记:(TOG2019)DGCNN : Dynamic Graph CNN for Learning on Point Clouds

    目录 摘要 一.引言 二.相关工作 三.我们的方法 3.1 边缘卷积Edge Convolution 3.2动态图更新 3.3 性质 3.4 与现有方法比较 四.评估 4.1 分类 4.2 模型复杂度 ...

  10. Python中input()函数用法

    input()函数获取用户输入数据,实现用户交互 语法格式: 变量 = input("提示信息") input()返回的是字符串,无论输入的是数字还是字符串,默认的输入结束键是回车 ...