0.Seata官方文档
1.Seata概念及原理
-
Seata是什么
- Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
-
Seata主要由三个重要组件组成
- TC(Transaction Coordinator):事务协调器,管理全局的分支事务的状态,用于全局性事务的提交和回滚
- TM(Transaction Manager):事务管理器,用于开启、提交或者回滚全局事务
- RM(Resource Manager):资源管理器,用于分支事务上的资源管理,向TC注册分支事务、上报分支事务的状态、接受TC的命令来提交或者回滚分支事务
- 传统XA协议实现2PC方案的RM是在数据库层,RM本质上就是数据库自身
- Seata的RM是以jar包的形式嵌入在应用程序里面
-
架构理解:TC为单独部署的Server服务端,TM和RM为嵌入到应用中的Client客户端
-
其它术语
- XID:TM请求TC开启一个全局事务,TC会生成一个XID作为该全局事务的编号,XID会在微服务的调用链路中传播,保证将多个微服务的子事务关联在一起
-
Seata事务处理过程描述
- A服务的TM向TC申请开启(begin)一个全局事务,全局事务创建成功并生成一个全局唯一的XID
- A服务的RM向TC注册分支事务
- A服务执行分支事务,对数据库进行操作
- A服务远程调用B服务,并把XID在微服务调用链路的上下文中传播
- B服务的RM向TC注册分支事务,并将其纳入XID对应的全局事务的管辖
- B服务执行分支事务,对数据库进行操作
- 全局事务调用链处理完毕,TM根据有无异常向TC发起针对XID的全局提交(commit)或回滚(rollback)决议
- TC调度XID下管辖的全部分支事务完成提交(commit)或回滚(rollback)请求
-
Seata实现分布式事务,关键是UNDO_LOG(回滚日志记录表)
- 在每个应用需要分布式事务的业务库中创建这张表,这个表的核心作用是将业务数据在更新前后的数据镜像组织成回滚日志,保存在UNDO_LOG表中,以便业务异常能随时回滚
-
Seata有四种模式
-
AT
-
AT模式可以应对大多数的业务场景,并且基本可以做到无业务入侵,开发者无感知
-
用户只需关心自己的业务SQL,AT模式分为两个阶段,可以认为是2PC
-
一阶段:执行用户SQL
- Seata会拦截业务SQL,找到业务SQL要更新的业务数据,在业务数据被更新前,将其保存为before image,然后执行业务SQL更新业务数据
- 在业务数据更新之后,再将其保存成after image,最后生成行锁
- 以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性
-
二阶段:Seata框架自动生成提交或者回滚
- 二阶段提交:因为业务SQL在一阶段已经提交至数据库,所以Seata框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可
- 二阶段回滚:还原业务数据,回滚方式便是用before image 还原业务数据;但在还原前要校验脏写,对比数据库当前业务数据和after image,如果两份数据完全一致就说明没有脏写,出现脏写就需要转人工处理
-
-
-
TCC
-
Sage
-
XA
-
2.Seata使用基于AT模式
-
创建undo_log表,每个库都需要
CREATE TABLE IF NOT EXISTS `undo_log` (`branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',`xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table'; ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);
-
安装Seata服务器,本人使用docker安装
docker run -d --name gen-seata \-p 18091:8091 \seataio/seata-server:1.3.0
-
TC(事务协调器)需要存储全局事务和分支事务的记录,支持三种存储模式
- file模式(默认):性能高,适合单机模式,在内存中读写,并持久化到本地文件中
- 在bin/sessionStore/root.data文件
- db模式:性能较差,适合TC集群模式
- redis模式:性能较高,适合TC集群模式
- file模式(默认):性能高,适合单机模式,在内存中读写,并持久化到本地文件中
-
项目添加依赖
<!--Seata分布式事务:安装服务端版本需与客户端版本保持一致--> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><exclusions><exclusion><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId></exclusion></exclusions> </dependency> <dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.3.0</version> </dependency>
-
application.yml文件
# seata配置 seata:tx-service-group: gen-user-service-groupservice:grouplist:default: 114.132.67.61:18091vgroup-mapping:gen-user-service-group: default
-
在Service方法上增加注解@GlobalTransactional