Seata 是 阿里巴巴2019年开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。在 Seata 开源之前,Seata 对应的内部版本在阿里内部一直扮演着分布式一致性中间件的角色,帮助阿里度过历年的双11,对各业务进行了有力的支撑。经过多年沉淀与积累,2019.1 Seata 正式宣布对外开源 。目前 Seata 1.0 已经 GA。
让我们想象一下传统的单片应用程序,它的业务由3个模块组成,他们使用单个本地数据源。自然,本地事务将保证数据的一致性。
微服务架构已发生了变化。上面提到的3个模块被设计为3种服务。本地事务自然可以保证每个服务中的数据一致性。但是整个业务逻辑范围如何?
Seata怎么办?
我们说,分布式事务是由一批分支事务组成的全局事务,通常分支事务只是本地事务。
Seata有3个基本组成部分:
事务协调器(TC):维护全局事务和分支事务的状态,驱动全局提交或回滚。
事务管理器TM:定义全局事务的范围:开始全局事务,提交或回滚全局事务。
资源管理器(RM):管理正在处理的分支事务的资源,与TC对话以注册分支事务并报告分支事务的状态,并驱动分支事务的提交或回滚。
Seata管理的分布式事务的典型生命周期:
TM要求TC开始一项新的全局事务。TC生成代表全局事务的XID。
XID通过微服务的调用链传播。
RM将本地事务注册为XID到TC的相应全局事务的分支。
TM要求TC提交或回退相应的XID全局事务。
TC驱动XID的相应全局事务下的所有分支事务以完成分支提交或回滚。
用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:
仓储服务:对给定的商品扣除仓储数量。
订单服务:根据采购需求创建订单。
账户服务:从用户帐户中扣除余额。
seata AT 模式需要 undo_log 表,另外三张是业务表。
Server端存储模式(store.mode)现有file、db两种(后续将引入raft),file模式无需改动,直接启动即可。db模式需要导入用于存储全局事务回话信息的三张表。
可以直接通过bash 脚本启动 Seata Server,也可以通过 Docker 镜像启动,但是 Docker 方式目前只支持使用 file 模式,不支持将 Seata-Server 注册到 Eureka 或 Nacos 等注册中心。
在 https://github.com/seata/seata/releases 下载相应版本的 Seata Server,解压后执行以下命令启动,这里使用 file 配置
项目名 | 地址 | 说明 |
---|---|---|
sbm-account-service | 127.0.0.1:8081 | 账户服务 |
sbm-order-service | 127.0.0.1:8082 | 订单服务 |
sbm-storage-service | 127.0.0.1:8083 | 仓储服务 |
sbm-business-service | 127.0.0.1:8084 | 主业务 |
seata-server | 172.16.2.101:8091 | seata-server |
为了不让篇幅太长,这里只给出部分代码,详细代码文末会给出源码地址
maven 引入 seata 的依赖 eata-spring-boot-starter
只需要使用一个 @GlobalTransactional 注解在业务方法上。
全局事务ID的跨服务传递,需要我们自己实现,这里通过拦截器的方式。每个服务都需要添加下面两个类。
此时返回结果为:true
UserId 为1002 的用户下单,sbm-account-service会抛出异常,事务会回滚
此时返回结果为:false
查看 undo_log 的日志或者主键,可以看到在执行过程中有保存数据。如查看主键自增的值,在执行前后的值会发生变化,在执行前是 1,执行后是 7 。
https://github.com/gf-huanchupk/SpringBootLearning/tree/master/springboot-seata
http://seata.io/zh-cn/docs/overview/what-is-seata.html
-- END --
每一个“ 在 看 ”,都是对我最大的肯定 !