GitHub项目地址:seata-spring-boot-demos
一、什么是Seata?
官网地址:https://seata.io
提炼关键词:
特性:
1、一致性(这个是痛点,解决的就是微服务分布式事务一致性的问题)
2、高性能(这个是卖点,如果用了反而拖累整个微服务架构的性能,试问谁还会用呢?)
3、易用性(这个是亮点,大家开发时引入新技术,都希望简单好用,如果技术太过于复杂,反而会提升使用门槛,吓跑用户)
事务模式
- AT (Automatic Transaction,对业务系统无侵入,省去了用的人很多编码的工作)
- TCC(Try-Confirm-Cancel,对业务系统有侵入,用的时候需要自己写大量的代码)
- Saga (Long Live Transaction,长事务解决方案,对业务系统有侵入,同TCC)
- XA ( X/Open 组织提出的分布式事务处理的规范,对业务系统无侵入,只需要DB实现了XA协议即可)
文章推荐:带你读透 SEATA 的 AT 模式
这篇文章讲的很好,很适合结合着Seata官方文档细细品读,下面放几张文中的关键图
Seata-AT模式最初的构想
- 每个应用服务对应一个本地数据库,即database per service;
- 每个应用服务之间互相协作,调用接口;
- 每个应用服务执行自己的SQL脚本;
- 每个应用服务执行自己的SQL语句时,是基于本地事务的;
- 每个应用服务对应的本地库中,都存在一个UNDO Log(回滚日志记录);
- 每个应用服务实现自己的事务提交,如果有一个事务提交失败,则全局回滚;
- 发生全局事务回滚时,则每个分支(本地)事务按照UNDO log内容对数据集进行反向补偿(反向SQL)
Seata分布式事务中间件架构图
搞懂上图,需要知道Seata的三个角色概念:
- TC(Trasaction Cordornator,事务协调器)
- TM(Transaction Manager,事务管理器)
- RM (Resource Manager,资源管理器)
其中TC对应的应用服务就是seata-server
TC角色主要用来和TM和RM进行“交流”的,通过rpc(Netty)+服务注册发现(nacos等),实现与各个微服务模块之间的通信
其中TM对应的应用服务就是开启了@GlobalTransactional注解的业务方法所在的微服务模块,即seata-business-server
TM角色主要定义了全局事务的边界,用来向TC开启一个全局事务,拿到全局事务唯一的XID,并在调用的微服务之间的上下文中进行传递,同时,该服务还掌握着是否全局提交还是全局回滚的决议权!
TM#开启全局事务1#TransactionalTemplate.beginTransaction(...)
TM#开启全局事务2#DefaultGlobalTransaction.begin(int timeout, String name)
TM#开启全局事务3#DefaultTransactionManager .begin(.....)
TM#开启全局事务4#AbstractNettyRemoting.sendSync(.....)
TM端调用结束,我们接下来看下TC端
TC#开启全局事务1#DefaultCoordinator.doGlobalBegin(.....)TC#开启全局事务2#DefaultCore.begin(.....)
TC#开启全局事务3#GlobalSession.begin()
TC#开启全局事务4#DataBaseSessionManager.addGlobalSession(GlobalSession session)
TC#开启全局事务4#DataBaseTransactionStoreManager .writeSession (....)
TC#开启全局事务5#LogStoreDataBaseDAO .insertGlobalTransactionDO (....)
执行完后,看下数据库
全局提交的条件是:各个微服务的分支事务均提交成功;
全局回滚的条件是:只要有一个微服务的分支事务提交失败,就会触发整个全局事务的回滚!
其中RM对应的应用服务就是在业务上存在SQL语句执行的微服务模块,如order-server
RM角色主要用来向TC注册分支事务(保存到seata库对应的branch_table表中),并上报分支事务提交和回滚的状态给TC,TC根据分支事务提交和回滚的状态来驱动TM最终进行全局的提交或全局的回滚;
(关于RM和TC交互的代码调试就不放了,下面放几张和分支事务有关的截图吧,有问题的可以留言)
库存服务(RM)对应的初始化商品的库存记录如下:
TC分支事务表记录如下:
库存服务(RM)在TM开启全局事务后,执行减库存操作但事务未提交时的分支事务记录如下:
库存服务(RM)在TM开启全局事务后,执行减库存操作但事务未提交时的分支回滚记录如下:
每个分支事务都对应一条undo_log记录,我们导出减库存的log后,查看其内容如下:
最后执行成果后,相应的undo_log记录会被删除,刷新库存的undo_log表记录如下:
最终,我们可以看到,水杯的库存量为:
如果TM发起全局提交,则TC会分别调用各个微服务,并对各个RM中的undo_log表中的XID记录进行异步删除;
如果TM发起全局回滚,则TC会分别调用各个微服务,并对各个RM中的undo_log表中的XID记录进行反向SQL,恢复事务操作前的数据;
二、Seata源码编译
未完待续,.................
三、Seata服务参数配置
未完待续,.................
四、Seata服务启动
未完待续,.................