侧边栏壁纸
博主头像
再见理想博主等级

只争朝夕,不负韶华

  • 累计撰写 112 篇文章
  • 累计创建 64 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

分布式事务- Seata实现2PC事务(强一致性)

再见理想
2022-07-19 / 0 评论 / 0 点赞 / 401 阅读 / 1,187 字

一,简介

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

1.1,三种角色

1,Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。

2,Transaction Manager ™: 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。

3,Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。

其中,TM是一个分布式事务的发起者和终结者,TC负责维护分布式事务的运行状态,而RM则负责本地事务的运行。如下图所示:

img

1.2,Seata实现2PC与传统2PC的差别

架构层次方面,传统 2PC 方案的 RM 实际上是在数据库层,RM 本质上就是数据库自身,通过 XA 协议实现,而会Seata 的 RM 是以 jar 包的形式作为中间件层部署在应用程序这一侧的。

两阶段提交方面,传统2PC无论第二阶段的决议是 commit 还是 rollback,事务性资源的锁都要保持到第二阶段完成才释放。而Seata的做法是在第一阶段就将本地事务提交,这样就可以省去第二阶段持锁的时间,整体提高效率。

二,一个分布式事务在Seata中的执行流程

① TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID,
XID 在微服务调用链路的上下文中传播。

② RM 向 TC 注册分支事务,接着执行这个分支事务并提交(重点:RM在第一阶段就已经执行了本地事务的提交/回滚),最后将执行结果汇报给TC。

③ TM 根据 TC 中所有的分支事务的执行情况,发起全局提交或回滚决议。

④ TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。

img

2.1,Seata 执行流程要点

1、每个RM使用 DataSourceProxy 连接数据库,其目的是使用 ConnectionProxy,使用数据源和数据连接代理的目的就是在第一阶段将 undo_log 和业务数据放在一个本地事务提交,这样就保存了只要有业务操作就一定有undo_log。

2、在第一阶段 undo_log 中存放了数据修改前和修改后的值,为事务回滚作好准备,所以第一阶段完成就已经将分支事务提交,也就释放了锁资源。

3、TM 开启全局事务开始,将 XID 全局事务id放在事务上下文中,通过 feign 调用也将 XID 传入下游分支事务,每个分支事务将自己的 Branch ID 分支事务 ID 与 XID 关联

4、第二阶段全局事务提交,TC 会通知各各分支参与者提交分支事务,在第一阶段就已经提交了分支事务,这里各各参与者只需要删除 undo_log 即可,并且可以异步执行,第二阶段很快可以完成。

5、第二阶段全局事务回滚,TC 会通知各各分支参与者回滚分支事务,通过 XID 和 Branch ID 找到相应的回滚日志,通过回滚日志生成反向的 SQL 并执行,以完成分支事务回滚到之前的状态,如果回滚失败则会重试回滚操作。

2.2,Seata实现2PC要点

1、全局事务开始使用 @GlobalTransactional标识 。

GlobalTransactionalInterceptor 会拦截 @GlobalTransactional 注解的方法,生成全局事务 ID(XID),XID 会在整个分布式事务中传递。在远程调用时,spring-cloud-alibaba-seata 会拦截 Feign 调用将 XID 传递到下游服务。

2、每个本地事务方案仍然使用 @Transactional 标识。

3、每个数据都需要创建 undo_log 表,此表是 seata 保证本地事务一致性的关键。

0

评论区