0. 前置知识
0.1 事务的一些基本概念
- 上篇说了事务的一些概念和Spring中的一些接口定义以及单数据源事务的实现具体的自己点下链接看吧
https://blog.csdn.net/ilo114/article/details/103937092
0.2 X/OPEN DTP模型
- 全称:X/Open Distributed Transaction Processing Reference Model, 也就是一个分布式事务处理的模型
- DTP定义的三个组成部分,分别是:AP(Application Program,应用程序)、RM(Resource Manager,资源管理器)、TM(Transaction Manager,事务管理器)
- AP:就是使用DTP模型的程序
- RM:资源管理器(可以理解为数据库系统、消息队列系统)
- TM:事务管理器
0.3 X/OPEN XA规范
- wiki:https://zh.wikipedia.org/wiki/X/Open_XA
- XA规范就是提供一套通用的调用接口规范让TM可以调用不同的RM,也是让不同RM根据XA规范来实现自己的RM。
- XA使用两阶段提交(2PC)来保证所有资源同时提交或回滚任何特定的事务
MySQL的InnoDB存储引擎支持XA规范。
0.4 2PC 两阶段提交
- wiki: https://zh.wikipedia.org/wiki/%E4%BA%8C%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4
- 两阶段提交,顾名思义把事务的执行分成了两个阶段,第一个阶段就是提交请求或者说投票阶段,事务管理器把要执行的任务告诉资源管理器,并问它可不可以做?多个资源管理器分别回复给OK和不OK; 第二个阶段就是执行阶段:事务管理器收到各个资源管理器的回复,如果全是OK那就干!如果有不OK的那就不干了。
- 详细的可以看下wiki 很详细
0.5 JTA Java事务API
- 全称是:Java Transaction API,是JSR 907规范提出的 允许完成跨越多个XA资源的分布式事务编程接口,它包括用户操作接口,JTATransactionManager,XAResource.
- 它是XA规范在Java中的实现。
- 我们在接下来的实例中就会使用JTA事务管理器来管理两个数据库操作的事务。
1. 多数据源事务管理
1.1 环境说明
1.1.1 组件说明
- DataSource: Alibaba Druid
- Database: MySQL 5.7
- SpringBoot: 2.2.2.RELEASE
- ORM: MyBatis
- JTA: Atomikos
- GitHub: https://github.com/imyiren/transaction-example/tree/master/two-data-source
1.1.2 项目关键依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!--atomikos transaction management-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
1.1.3 多数据源
- 数据源使用两个数据库的不同表
- 都是用Druid做连接池,然后用Atomikos管理
1.1.4 JTA的工具
- SpringBoot可以用的官方说了两个一个是Atomikos,另一个是Bitronix,除此之外还可以在支持JTA的web server中用。(Tomcat不支持)
- SpringBoot文档中的说明:当检测到JTA环境时,将使用Spring的JtaTransactionManager来管理事务。JMS、DataSource、JPA已升级为支持XA事务。可以用标准的Spring用法(例如@Transactional)来参与分布式事务。如果您在JTA环境中,并且仍要使用本地事务,则可以将spring.jta.enabled属性设置为false以禁用JTA自动配置。
1.2 实例业务说明
- 简单逻辑,两张表,分别在两个不同的库中,然后一个service方法操作两个库的数据。
1.3 多数据源配置
1.3.1 配置文件
- 第一张表:是账户表
- 第二章表:是订单表
spring:
application:
name: two-data-source
datasource:
account:
url: jdbc:mysql://127.0.0.1:3306/transaction_account?useSSL=false&characterEncoding=UTF-8
username: root
password: xxxxx
order:
url: jdbc:mysql://127.0.0.1:3306/transaction_order?useSSL=false&characterEncoding=UTF-8
username: root
password: xxxxx
#logging:
# level:
# root: DEBUG
1.3.2 Bean注册
- 主要包括以下步骤
- 分别注册对应DataSource、SqlSessionFactory、SqlSessionTemplate的Bean
- 然后指定表的Mapper的位置,并且把template设置成你注册的。
- order库的类似 此处略
- 需要注意的点:
- DataSource不能直接使用Druid提供的DruidDataSource, 需要使用atomikos来包装一下Druid提供的DruidXADataSource,来支持XA规范
- 如果你不想用Druid,可以考虑使用MysqlXADataSource(我没试过)
- 注册的Bean的对应关系要正确
@Configuration
@MapperScan(basePackages = {
"io.ilss.transaction.twodatasource.dao.account"}, sqlSessionTemplateRef = "accountSqlSessionTemplate")
public class AccountConfiguration {
@Value("${spring.datasource.account.url}")
private String url;
@Valu

本文深入探讨了在Spring Boot环境下如何配置和使用多数据源,以及通过JTA进行分布式事务管理的具体实践。文章详细讲解了使用Atomikos作为JTA事务管理器,配合Druid数据源和MyBatis ORM框架,在两个不同数据库间实现一致性的事务处理流程。


被折叠的 条评论
为什么被折叠?



