diff --git a/README.md b/README.md
index 7a99975..fdfb683 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,12 @@ spring-boot:2.1.1.RELEASE
spring-cloud:Finchley.SR2
+**更新日志**:
+
+>2019.01.27 新增用例 : [spring boot + druid + mybatis + atomikos](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/[springboot-druid-mybatis-multi) 配置多数据源、支持分布式事务( JTA方式实现)
+
+
+
## 1. spring samples
所有spring的项目我都会提供两个版本的sample:
@@ -79,10 +85,11 @@ spring-cloud:Finchley.SR2
## 4.spring分布式session和分布式事务
-| sample | 描述 | 官方文档 |
-| ------------------------------------------------------------ | ----------------------------------------------- | ------------------------------------------------------------ |
-| [spring-session](https://github.com/heibaiying/spring-samples-for-all/tree/master/distributed-solution/spring-session) | spring 实现分布式 session | [spring session](https://spring.io/projects/spring-session#learn) |
-| [spring boot + spring session](https://github.com/heibaiying/spring-samples-for-all/tree/master/distributed-solution/spring-boot-session) | spring boot + spring session 实现分布式 session | [spring session](https://spring.io/projects/spring-session#learn) |
+| sample | 描述 | 官方文档 |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [spring-session](https://github.com/heibaiying/spring-samples-for-all/tree/master/distributed-solution/spring-session) | spring 实现分布式 session | [spring session](https://spring.io/projects/spring-session#learn) |
+| [spring boot + spring session](https://github.com/heibaiying/spring-samples-for-all/tree/master/distributed-solution/spring-boot-session) | spring boot + spring session 实现分布式 session | [spring session](https://spring.io/projects/spring-session#learn) |
+| [springboot-druid-mybatis-atomikos](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/[springboot-druid-mybatis-multi) | spring boot + druid + mybatis + atomikos
配置多数据源、支持分布式事务( JTA 方式实现) | [Distributed Transactions with JTA](https://docs.spring.io/spring-boot/docs/2.1.2.RELEASE/reference/htmlsingle/#boot-features-jta) |
diff --git a/pictures/DefaultSqlSessionFactory.png b/pictures/DefaultSqlSessionFactory.png
new file mode 100644
index 0000000..a0e2399
Binary files /dev/null and b/pictures/DefaultSqlSessionFactory.png differ
diff --git a/pictures/XA.gif b/pictures/XA.gif
new file mode 100644
index 0000000..122285e
Binary files /dev/null and b/pictures/XA.gif differ
diff --git a/pictures/commit.png b/pictures/commit.png
new file mode 100644
index 0000000..8c3624a
Binary files /dev/null and b/pictures/commit.png differ
diff --git a/pictures/customSqlSessionTemplate.png b/pictures/customSqlSessionTemplate.png
new file mode 100644
index 0000000..89637a7
Binary files /dev/null and b/pictures/customSqlSessionTemplate.png differ
diff --git a/pictures/druid-mysql01.png b/pictures/druid-mysql01.png
new file mode 100644
index 0000000..d6ec463
Binary files /dev/null and b/pictures/druid-mysql01.png differ
diff --git a/pictures/durid-mysql-weburl.png b/pictures/durid-mysql-weburl.png
new file mode 100644
index 0000000..23eb408
Binary files /dev/null and b/pictures/durid-mysql-weburl.png differ
diff --git a/pictures/durud-mysql02.png b/pictures/durud-mysql02.png
new file mode 100644
index 0000000..28f13d7
Binary files /dev/null and b/pictures/durud-mysql02.png differ
diff --git a/pictures/getsqlSession.png b/pictures/getsqlSession.png
new file mode 100644
index 0000000..dd77a6f
Binary files /dev/null and b/pictures/getsqlSession.png differ
diff --git a/pictures/mysql01.png b/pictures/mysql01.png
new file mode 100644
index 0000000..5aa1b15
Binary files /dev/null and b/pictures/mysql01.png differ
diff --git a/pictures/mysql0102.png b/pictures/mysql0102.png
new file mode 100644
index 0000000..5d76b76
Binary files /dev/null and b/pictures/mysql0102.png differ
diff --git a/pictures/mysql02.png b/pictures/mysql02.png
new file mode 100644
index 0000000..b8f9084
Binary files /dev/null and b/pictures/mysql02.png differ
diff --git a/pictures/opneConnection.png b/pictures/opneConnection.png
new file mode 100644
index 0000000..aefa530
Binary files /dev/null and b/pictures/opneConnection.png differ
diff --git a/pictures/springManagerTransaction.png b/pictures/springManagerTransaction.png
new file mode 100644
index 0000000..bf586ad
Binary files /dev/null and b/pictures/springManagerTransaction.png differ
diff --git a/pictures/springboot-druid-mybatis-multi-test.png b/pictures/springboot-druid-mybatis-multi-test.png
new file mode 100644
index 0000000..7b80715
Binary files /dev/null and b/pictures/springboot-druid-mybatis-multi-test.png differ
diff --git a/pictures/springboot-druid-mybatis-multi.png b/pictures/springboot-druid-mybatis-multi.png
new file mode 100644
index 0000000..892051b
Binary files /dev/null and b/pictures/springboot-druid-mybatis-multi.png differ
diff --git a/pictures/sqlSession.png b/pictures/sqlSession.png
new file mode 100644
index 0000000..698e519
Binary files /dev/null and b/pictures/sqlSession.png differ
diff --git a/pictures/sqlSessionFactory.png b/pictures/sqlSessionFactory.png
new file mode 100644
index 0000000..1318aeb
Binary files /dev/null and b/pictures/sqlSessionFactory.png differ
diff --git a/pictures/sqlSessionTemplate.png b/pictures/sqlSessionTemplate.png
new file mode 100644
index 0000000..b4591ac
Binary files /dev/null and b/pictures/sqlSessionTemplate.png differ
diff --git a/spring-boot/springboot-druid-mybatis-multi/README.md b/spring-boot/springboot-druid-mybatis-multi/README.md
new file mode 100644
index 0000000..1f25675
--- /dev/null
+++ b/spring-boot/springboot-druid-mybatis-multi/README.md
@@ -0,0 +1,758 @@
+# spring boot + druid + mybatis + atomikos 配置多数据源 并支持分布式事务
+
+## 一、综述
+
+### 1.1 项目说明
+
+本用例基于spring boot + druid + mybatis 配置多数据源,并采用 **JTA 实现分布式事务**。
+
+### 1.2 项目结构
+
+主要配置如下:
+
+
+
+
+
+
+
+## 二、配置多数据源并支持分布式事务
+
+### 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
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 1.3.2
+
+
+
+ mysql
+ mysql-connector-java
+ 6.0.6
+
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ 1.1.10
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jta-atomikos
+
+
+ org.projectlombok
+ lombok
+ true
+
+```
+
+### 2.2 在yml中配置多数据源信息
+
+**注意**:Spring Boot 2.X 版本不再支持配置继承,多数据源的话每个数据源的所有配置都需要单独配置,否则配置不会生效。
+
+这里我用的本地数据库mysql和mysql02,配置如下:
+
+```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
+ url-pattern: /*
+ # 排除静态资源的请求
+ exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
+
+ # Druid内置提供了一个StatViewServlet用于展示Druid的统计信息。
+ stat-view-servlet:
+ #是否启用StatViewServlet 默认值true
+ enabled: true
+ # 需要拦截的url
+ url-pattern: /druid/*
+ # 允许清空统计数据
+ reset-enable: true
+ login-username: druid
+ login-password: druid
+```
+
+
+
+### 2.3 进行多数据源的配置
+
+#### 1. 在启动类关闭springboot对数据源的自动化配置,由我们手动进行多数据源的配置
+
+```java
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
+public class DruidMybatisMultiApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(DruidMybatisMultiApplication.class, args);
+ }
+
+}
+```
+
+#### 2. 创建多数据源配置类`DataSourceFactory.java`, 手动配置多数据源
+
++ 这里我们创建druid数据源的时候,创建的是`DruidXADataSource`,它继承自`DruidDataSource `并支持XA分布式事务;
++ 使用 `AtomikosDataSourceBean` 包装我们创建的`DruidXADataSource`,使得数据源能够被 JTA 事务管理器管理;
++ 这里我们使用的sqlSessionTemplate是我们重写的`CustomSqlSessionTemplate`,原生的sqlSessionTemplate在@Transactional 注解下,是不能实现在一个事务中实现数据源切换的。(为了不占用篇幅,我会在后文再给出详细的原因分析)
+
+```java
+/**
+ * @author : heibaiying
+ * @description : 多数据源配置
+ */
+@Configuration
+@MapperScan(basePackages = DataSourceFactory.BASE_PACKAGES, sqlSessionTemplateRef = "sqlSessionTemplate")
+public class DataSourceFactory {
+
+ static final String BASE_PACKAGES = "com.heibaiying.springboot.dao";
+
+ private static final String MAPPER_LOCATION = "classpath:mappers/*.xml";
+
+
+ /***
+ * 创建 DruidXADataSource 1 用@ConfigurationProperties自动配置属性
+ */
+ @Bean
+ @ConfigurationProperties("spring.datasource.druid.db1")
+ public DataSource druidDataSourceOne() {
+ return new DruidXADataSource();
+ }
+
+ /***
+ * 创建 DruidXADataSource 2
+ */
+ @Bean
+ @ConfigurationProperties("spring.datasource.druid.db2")
+ public DataSource druidDataSourceTwo() {
+ return new DruidXADataSource();
+ }
+
+ /**
+ * 创建支持XA事务的Atomikos数据源1
+ */
+ @Bean
+ public DataSource dataSourceOne(DataSource druidDataSourceOne) {
+ AtomikosDataSourceBean sourceBean = new AtomikosDataSourceBean();
+ sourceBean.setXaDataSource((DruidXADataSource) druidDataSourceOne);
+ // 必须为数据源指定唯一标识
+ sourceBean.setUniqueResourceName("db1");
+ return sourceBean;
+ }
+
+ /**
+ * 创建支持XA事务的Atomikos数据源2
+ */
+ @Bean
+ public DataSource dataSourceTwo(DataSource druidDataSourceTwo) {
+ AtomikosDataSourceBean sourceBean = new AtomikosDataSourceBean();
+ sourceBean.setXaDataSource((DruidXADataSource) druidDataSourceTwo);
+ sourceBean.setUniqueResourceName("db2");
+ return sourceBean;
+ }
+
+
+ /**
+ * @param dataSourceOne 数据源1
+ * @return 数据源1的会话工厂
+ */
+ @Bean
+ public SqlSessionFactory sqlSessionFactoryOne(DataSource dataSourceOne)
+ throws Exception {
+ return createSqlSessionFactory(dataSourceOne);
+ }
+
+
+ /**
+ * @param dataSourceTwo 数据源2
+ * @return 数据源2的会话工厂
+ */
+ @Bean
+ public SqlSessionFactory sqlSessionFactoryTwo(DataSource dataSourceTwo)
+ throws Exception {
+ return createSqlSessionFactory(dataSourceTwo);
+ }
+
+
+ /***
+ * sqlSessionTemplate与Spring事务管理一起使用,以确保使用的实际SqlSession是与当前Spring事务关联的,
+ * 此外它还管理会话生命周期,包括根据Spring事务配置根据需要关闭,提交或回滚会话
+ * @param sqlSessionFactoryOne 数据源1
+ * @param sqlSessionFactoryTwo 数据源2
+ */
+ @Bean
+ public CustomSqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactoryOne,
+ SqlSessionFactory sqlSessionFactoryTwo) {
+ Map