分布式事务
在分布式系统中,如果一个业务需要多个服务合作完成,而且每一个服务都有事务,多个事务必须同时成功或失败,这样的事务就是分布式事务,其中每个事务就是一个分支事务,整个业务的事务称为全局事务
要解决分布式事务,各个子事务之间必须能感知到彼此的事务状态,才能保证状态一致
我们需要一个事务协调者
Seata
Seata是蚂蚁金服和阿里巴巴共同开源的分布式事务框架解决方案
官方地址:http://seata.io/
Seata事务管理中由三个重要的角色:
TC-事务协调者
:维护全局和分支事务的状态,协调全局事务提交或回滚
TM-事务管理器
:定义全局事务的范围,开始全局事务,提交或回滚全局事务
RM-资源管理器
:管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态
- 部署TC服务
Seata由于需要记录信息,所以需要数据存储,Seata支持多种存储模式,但考虑到持久化问题,我们一般选择数据库存储
分别是分支表
,分布式锁
,全局表
,锁
然后在虚拟机中通过Docker安装Seata
微服务集成Seata
- 在项目中引入Seata依赖:
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency>
- 在application.yml中添加配置,让微服务找到TC服务地址
seata:registry: #注册中心的配置,微服务根据这些信息去注册中心获取TC服务地址type: nacos #注册中心类型nacos:server-addr: 服务器地址:8848namespace: ""group: DEFAULT_GROUPapplication: seata-server #seata服务名称username: nacospassword: nacostx-service-group: dada #事务组名称service:vgroup-mapping: #事务组与TC集群的映射关系dada: "default"
Seata为用户提供了,AT,TCC,SAGA,XA事务模式进行分布式任务管理
XA模式
XA规范是X/Open组织定义的分布式事务处理(DTP)标准,XA规范,描述了全局的TM与局部的RM之间的接口,几乎所有的主流的数据库都对XA规范提供了支持
在第一阶段:
- RM注册分支事务到TC
- RM执行分支业务sql但不提交
- RM报告执行状态到TC
在第二阶段:
- TC检测各分支事务执行状态
都成功
:通知所有的RM提交事务
有失败
:通知所有的RM回滚事务 - RM接收到TC指令,提交或回滚事务
- 优点
事务的强一致性,满足ACID原则,常用的数据库都支持
- 缺点
一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差,依赖关系型数据库实现事务
XA模式使用
1 .修改application.yml文件(每个参与事务的微服务),开启XA模式
seata:data-source-proxy-mode: XA # 开启数据源代理的XA模式
- 给发起全局事务的入口方法添加 @GlobalTransactional注解
AT模式
Seata主推的是AT模式,AT模式同样是分阶段提交的事务模型,弥补了XA模型中资源锁定周期过长的缺陷
阶段一:
- 注册分支事务
- 记录undo-log(数据快照)
- 执行业务sql并提交
- 报告事务状态
阶段二:
成功
:RM删除undo-log
失败
:根据undo-log恢复数据到更新前,进行回滚
AT模式实现
- 数据快照需要一张单独的表来存储数据快照(每一个微服务中都需要有一张)
- 修改application.yml文件,将事务模式修改为AT模式
seata:data-source-proxy-mode: AT #开启数据源代理的AT模式
- XA与AT的区别:
- XA模式一阶段不提交事务,AT提交
- XA模式依赖数据库进行回滚,AT模式利用数据快照实现数据回滚
- XA模式强一致,AT模式最终一致