概念
Fescar/Seata 是 阿里巴巴 开源的 分布式事务中间件,以 高效 并且对业务 0 侵入 的方式,解决 微服务 场景下面临的分布式事务问题。
参考资料:
[https://github.com/seata/seata/wiki/%E6%A6%82%E8%A7%88]
(https://github.com/seata/seata/wiki/%E6%A6%82%E8%A7%88)
[https://github.com/seata/seata/wiki/Home_Chinese
(https://github.com/seata/seata/wiki/Home_Chinese)
https://toutiao.io/tags/Seata
[https://www.jianshu.com/p/940e2cfab67e]
(https://www.jianshu.com/p/940e2cfab67e)
[https://www.cnblogs.com/smileIce/p/11200829.html]
(https://www.cnblogs.com/smileIce/p/11200829.html)-
发展历程
2014 年,阿里中间件团队发布 TXC(Taobao Transaction Constructor),为集团内应用提供分布式事务服务。
2016 年,TXC 经过产品化改造,以 GTS(Global Transaction Service) 的身份登陆阿里云,成为当时业界唯一一款云上分布式事务产品,在阿云里的公有云、专有云解决方案中,开始服务于众多外部客户。
2019 年起,基于 TXC 和 GTS 的技术积累,阿里中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback, FESCAR),和社区一起建设这个分布式事务解决方案。
Fescar 开源后,蚂蚁金服加入 Fescar 社区参与共建,并在 Fescar 0.4.0 版本中贡献了 TCC 模式。
为了打造更中立、更开放、生态更加丰富的分布式事务开源社区,经过社区核心成员的投票,大家决定对 Fescar 进行品牌升级,并更名为 Seata,意为:Simple Extensible Autonomous Transaction Architecture,是一套一站式分布式事务解决方案。
Seata-Server设计
seata-server是一个单独进程服务,与TM/RM的交互是RPC
1)Coordinator Core:最下面的模块是事务协调器核心代码,主要用来处理事务协调的逻辑,如是否 Commit、Rollback 等协调活动。
2)Store:存储模块,用来将我们的数据持久化,防止重启或者宕机数据丢失。
3)Discover:服务注册/发现模块,用于将 Server 地址暴露给 Client。
4)Config:用来存储和查找服务端的配置。
5)Lock:锁模块,用于给 Seata 提供全局锁的功能。
6)Rpc:用于和其他端通信。
7)HA-Cluster:高可用集群,目前还没开源。为 Seata 提供可靠的高可用功能。
-
核心组件
TC: 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚(server端)。
TM: 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议(client端)。
RM:控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚(client端)。
开启全局事物
以@GlobalTransactional为入口,GlobalTransactionalInterceptor为切入点,稍后会讲到
TM会向TC发起一个请求(服务端使用的netty)开启一个全局事物,生成全局事物的XID,通过服务调用链路传播
开启分支事物
执行业务代码,准备开启分支事物。
分支事物开启的原理:
1.由于seata对底层的DataSource,Connection等使用DataSourceProxy,ConnectionProxy代理
2.当进行数据库操作的时候,ConnectionProxy会判断是否包含全局事物
2.1 包含全局食物
2.1.1 RM向TC发起请求注册分支事物
2.1.2 插入回滚日志(undo_log表,业务库必须新建这个表)
2.1.3 事物提交
2.1.4 向TC上报事物状态
2.2 不包含全局事物
2.2.1 事物提交
** 全局事物提交**
当业务逻辑执行没问题的话,就需要执行全局事物的提交。
1.TM向TC发起全局事物提交请求
2.TC收到之后,会向各个分支事发起事物提交请求
3.分支事物接收到请求,只需要删除全局事物的undo_log记录就可以了
全局事物回滚
当业务逻辑执行发生异常,就需要执行全局事物的回滚。
1.TM向TC发起全局事物回滚请求
2.TC收到之后,会向各个分支事发起事物回滚请求
3.分支事物接收到请求,只需要根据XID对应的undo_log表记录进行回滚即可(记录执行前后的记录)
主要Class
| 组件 | Class |
| TC | DefaultCoordinator |
| TM | GlobalTransaction、GlobalTransactionalInterceptor、TransactionalTemplate |
| RM | DataSourceProxy、ConnectProxy |
** 原理**
以一个代码块说一下大概原理
下面方法会两件事
1.减库存
2.新增订单
具体的demo地址可以去我上面地址里面可以搜到
@GlobalTransactional(timeoutMills = 30000, name = "dubbo-demo-tx")
public void purchase(String userId, String commodityCode, int orderCount) {
LOGGER.info("purchase begin ... xid: " + RootContext.getXID());
storageService.deduct(commodityCode, orderCount);
orderService.create(userId, commodityCode, orderCount);
throw new RuntimeException("xxx");
}
GlobalTransactionalInterceptor 会进行拦截,最终会走到TransactionalTemplate的execute
分支事物的操作,是对DataSource,Connection,Statement进行了代理,所以带进行数据库操作的时候,首先以ConnectionProxy为入口
遗留问题
1.XID是怎么传递的?
2.TC、TM、RM 交互流程(具体RPC的详细流程)?
3.全局锁的原理?
4.undo_log的作用以及分支事物提交/回滚时的作用?
5.性能问题?