# Spring Boot + Druid + Mybatis + Atomikos 配置多数据源 并支持分布式事务
<nav>
<a href="#一项目综述">一、项目综述</a><br/>
<a href="#11-项目说明">1.1 项目说明</a><br/>
<a href="#12-项目结构">1.2 项目结构</a><br/>
<a href="#二配置多数据源并支持分布式事务">二、配置多数据源并支持分布式事务</a><br/>
<a href="#21--导入基本依赖">2.1 导入基本依赖</a><br/>
<a href="#22-配置多数据源">2.2 配置多数据源</a><br/>
<a href="#23-实现多数据源">2.3 实现多数据源</a><br/>
<a href="#三测试整合结果">三、测试整合结果</a><br/>
<a href="#31--测试数据库整合结果">3.1 测试数据库整合结果</a><br/>
<a href="#32-测试单数据库事务">3.2 测试单数据库事务</a><br/>
<a href="#33-测试分布式事务">3.3 测试分布式事务</a><br/>
<a href="#34-测试-Druid-数据源">3.4 测试 Druid 数据源</a><br/>
<a href="#四JTA与两阶段提交">四、JTA与两阶段提交</a><br/>
<a href="#41-XA-与-JTA">4.1 XA 与 JTA</a><br/>
<a href="#42-两阶段提交">4.2 两阶段提交</a><br/>
<a href="#五常见整合异常">五、常见整合异常</a><br/>
</nav>
## 一、项目综述
### 1.1 项目说明
本用例基于 Spring Boot + Druid + Mybatis 配置多数据源,并采用 JTA 实现分布式事务。
### 1.2 项目结构
主要配置如下:
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/springboot-druid-mybatis-multi.png"/> </div>
## 二、配置多数据源并支持分布式事务
### 2.1 导入基本依赖
除了 Mybatis 、Durid 等基本依赖外,由于我们是依靠切面来实现动态数据源的切换,所以还需要导入 AOP 依赖。另外还需要导入 spring-boot-starter-jta-atomikos,Spring Boot 通过 [Atomkos](http://www.atomikos.com/) 或 [Bitronix](http://docs.codehaus.org/display/BTM/Home) 等内嵌事务管理器来支持跨多个 XA 资源的分布式 JTA 事务,当发现 JTA 的依赖和环境时,Spring Boot 将使用 Spring 的 JtaTransactionManager 来管理事务,并且自动配置的 JMS,DataSource 和 JPA Beans 也会被升级以支持 XA 事务。
```xml
<!--mybatis starter-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--引入mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!--druid 依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--aop starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--web starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--分布式事务依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
```
### 2.2 配置多数据源
**注意**:Spring Boot 2.X 版本不再支持配置继承,多数据源的话每个数据源的所有配置都需要单独配置,否则配置不会生效。
```yml
spring:
datasource:
druid:
db1:
url: jdbc:mysql://127.0.0.1:3306/mysql?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
# 初始化时建立物理连接的个数。初始化发生在显示调用 init 方法,或者第一次 getConnection 时
initialSize: 5
# 最小连接池数量
minIdle: 5
# 最大连接池数量
maxActive: 10
# 获取连接时最大等待时间,单位毫秒。配置了 maxWait 之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置 useUnfairLock 属性为 true 使用非公平锁。
maxWait: 60000
# Destroy 线程会检测连接的间隔时间,如果连接空闲时间大于等于 minEvictableIdleTimeMillis 则关闭物理连接。
timeBetweenEvictionRunsMillis: 60000
# 连接保持空闲而不被驱逐的最小时间
minEvictableIdleTimeMillis: 300000
# 用来检测连接是否有效的 sql 因数据库方言而异, 例如 oracle 应该写成 SELECT 1 FROM DUAL
validationQuery: SELECT 1
# 建议配置为 true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,执行 validationQuery 检测连接是否有效。
testWhileIdle: true
# 申请连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。
testOnBorrow: false
# 归还连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。
testOnReturn: false
# 是否自动回收超时连接
removeAbandoned: true
# 超时时间 (以秒数为单位)
remove-abandoned-timeout: 1800
db2:
url: jdbc:mysql://127.0.0.1:3306/mysql02?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
# 初始化时建立物理连接的个数。初始化发生在显示调用 init 方法,或者第一次 getConnection 时
initialSize: 6
# 最小连接池数量
minIdle: 6
# 最大连接池数量
maxActive: 10
# 获取连接时最大等待时间,单位毫秒。配置了 maxWait 之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置 useUnfairLock 属性为 true 使用非公平锁。
maxWait: 60000
# Destroy 线程会检测连接的间隔时间,如果连接空闲时间大于等于 minEvictableIdleTimeMillis 则关闭物理连接。
timeBetweenEvictionRunsMillis: 60000
# 连接保持空闲而不被驱逐的最小时间
minEvictableIdleTimeMillis: 300000
# 用来检测连接是否有效的 sql 因数据库方言而异, 例如 oracle 应该写成 SELECT 1 FROM DUAL
validationQuery: SELECT 1
# 建议配置为 true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于 timeBetweenEvictionRunsMillis,执行 validationQuery 检测连接是否有效。
testWhileIdle: true
# 申请连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。
testOnBorrow: false
# 归还连接时执行 validationQuery 检测连接是否有效,做了这个配置会降低性能。
testOnReturn: false
# 是否自动回收超时连接
removeAbandoned: true
# 超时时间 (以秒数为单位)
remove-abandoned-timeout: 1800
# WebStatFilter 用于采集 web-jdbc 关联监控的数据。
web-stat-filter:
# 是否开启 WebStatFilter 默认是 true
enabled: true
# 需要拦截的 url
评论0