seata笔记
事务模式
- AT 默认与主推模式,需要依赖数据库ACID,使用jdbc连接
- Saga 长事务,外部数据库等无法使用Tcc模式进行补偿
- TCC 代码有侵入,需要写parper,commit,rollback代码,不需要ACID支持
- XA 需要数据支持XA模式
架构图
Spring cloud 集成 AT模式
- 使用注解@GlobalTransactional 开启全局事务
- 配置数据源代理:DataSourceProxy
AT 原理介绍
AT模式下seata使用演变的两阶段提交协议工作机制。
一阶段:
- 解析Sql,
- 查询前镜像。
- 更新
- 查询后镜像
- 插入回滚日志:把前后镜像数据以及业务 SQL 相关的信息组成一条回滚日志记录,插入到 UNDO_LOG 表中
- 注册本地事务,申请全局锁。
- 本地事务提交:业务数据的更新和前面步骤中生成的 UNDO LOG 一并提交
- 将本地事务提交的结果上报给 TC
二阶段回滚:
- 收到 TC 的分支回滚请求,开启一个本地事务,执行如下操作。
- 通过 XID 和 Branch ID 查找到相应的 UNDO LOG 记录。
- 数据校验:拿 UNDO LOG 中的后镜与当前数据进行比较,如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理,详细的说明在另外的文档中介绍。
- 根据 UNDO LOG 中的前镜像和业务 SQL 的相关信息生成并执行回滚的语句:
- 提交本地事务。并把本地事务的执行结果(即分支事务回滚的结果)上报给 TC
二阶段提交
- 收到 TC 的分支提交请求,把请求放入一个异步任务的队列中,马上返回提交成功的结果给 TC。
- 异步任务阶段的分支提交请求将异步和批量地删除相应 UNDO LOG 记录。
spring cloud 中seata实现方式:
- 自动配置类GlobalTransactionAutoConfiguration,引入GlobalTransactionScanner
- GlobalTransactionScanner 的类关系图。
其中AbstractAutoProxyCreator的wrapIfNecessary方法被重写,判断是否需要被带代理。通过代理的方式引入了GlobalTransactionalInterceptor类。 - 处理全局事务。
- 获取xid ,设置到ThreadLocal,方便传递
- feign中XID的传递。在 SeataFeignClientAutoConfiguration中配置了FeignClient的实现类SeataFeignClient, 在执行请求时将XID设置在header中传递到下游服务。
- 由于DataSourceProxy代理了DataSouce,获取的连接Connection也是代理连接ConnnectionProxy,注册分支事务,刷新undo_log,提交本地事务等。