分布式事务方案怎么调研选型?TCC、seataAT、 最终一致性事务的原理和优缺点都有什么?

分布式事务一直是微服务等分布式系统不得不面对的难题。目前主流的解决方案有以下几种。

  1. 基于阿里巴巴开源的seata AT模式分布式事务框架
  2. TCC 三段式提交事务方案(业界一般使用ByteTCC框架)
  3. 基于RocketMq 消息中间件实现最终一致性事务

下面基于这三种方式进行原理剖析对比选型以及各自的优缺点比较

一、Seata

分布式事务方案怎么调研选型?TCC、seataAT、 最终一致性事务的原理和优缺点都有什么?_第1张图片

  • TC:事务协调器。控制全局事务的开启,提交回滚。
  • TM:事务管理器,负责定义事务的边界,负责发起开启一个全局事务、提交事务,回滚事务。例如上图中。server-A调用server-B和server-C。则在server-A开启全局事务。
  • RM:资源管理器。事务执行者,控制本分支事务的提交和回滚。

原理过程:

  1. TM像TC发起全局事务,TC生成一个全局的唯一事务XID,返回给TM,
  2. xid可以在服务调用的上下文中进行传播。
  3. RM 向TC注册分支事务,并且纳入该xid全局事务的范围内
  4. TM向TC发起全局事务的提交和回滚
  5. TC控制各个RM事务的提交和回滚

AT 两段式提交

分布式事务方案怎么调研选型?TCC、seataAT、 最终一致性事务的原理和优缺点都有什么?_第2张图片

  • 上左图:阶段一提交成功,释放本地事务锁,阶段二什么也不做,因此seata比传统的两段式XA模式性能要好很多,真实业务中大部分事务也是成功的,没必要全程占有锁。
  • 上右图:只有当第二阶段全局回滚时才两个阶段都占有锁。

提交和回滚

分布式事务方案怎么调研选型?TCC、seataAT、 最终一致性事务的原理和优缺点都有什么?_第3张图片

阶段一:

备注:这里的undo_log是一张表,不是mysql 的undo log日志文件

  1. 本地服务开始解析sql语句
  2. 开始查询即将要更新的数据,备份为数据镜像
  3. 开始执行业务sql
  4. 查询更新后的数据镜像
  5. 将更新前的数据镜像转成sql,插入到分布式事务数据库undo_log 表,这是重点,当全局事务失败后,事务协调器TC将会通知该RM,利用undo_log对应的数据进行回滚。
  6. 开启提交本地事务前,向TC注册本分支事务
  7. 提交分支事务
  8. 事务提交后,向TC报告该分支事务的状态

阶段一是每个RM都会提交的分支事务,但是有可能某个RM会执行失败。所以在第二阶段全局提交事务,有可能会成功,也有可能会失败,只要有一个RM失败,全局事务都会失败。

所以第二阶段分为2种情况:

  • 全局事务成功:
    分布式事务方案怎么调研选型?TCC、seataAT、 最终一致性事务的原理和优缺点都有什么?_第4张图片
    第二阶段,如果全局事务成功,则直接删除undo_log对应的回滚数据日志即可,不需要再持有本地事务锁,所以Seata性能相对较高

  • 全局事务失败:
    分布式事务方案怎么调研选型?TCC、seataAT、 最终一致性事务的原理和优缺点都有什么?_第5张图片
    如果全局事务失败,则查找对应的undo_log日志回滚数据,然后删除undo_log日志

  • 优点:

  1. 实现简单,基本0代码耦合,只需要在TM的地方加一个全局事务注解即可。
  2. 性能优秀,第一阶段则释放本地锁
  3. TC可单独集群部署,架构清晰,高可用保证
  4. 使用简单,学习成本低,微服务可直接集成进来。

二、TCC

TCC 事务分为3个阶段,也称为三阶段提交

  • T:try
  • C:confirm
  • C:cancle
    一般会引入ByteTcc之类的框架,然后针对同一个接口的,写出对应上述的三种实现方式。
    例如扣减库存业务,按照正常只直接扣除。
    做了TCC后,需要拆解为3个步骤:
  1. try : 先不要直接减库存,可以用某个字段表示先冻结调需要扣减的部分
  2. confirm:如果try成功,则执行confirm逻辑,confirm里面则开始真正的扣减库存
  3. cancle: 如果try失败,则执行cancle实现代码,回滚之前的冻结数据。

这3个步骤均在ByteTcc 框架的协调下执行。

优点:严格保证分布式事务的执行,严格保证数据的准确性。当然,前提是三个阶段的的代码实现你得写对。适合绝对不能出错的金融业务。
缺点:方案落地实现麻烦,业务代码耦合超高。每个需要加事务的地方都都手写这3段代码。

二、基于RocketMq实现最终一致性

分布式事务方案怎么调研选型?TCC、seataAT、 最终一致性事务的原理和优缺点都有什么?_第6张图片

  • half message: 半消息,也就是消息发送到rocket mq broker后,这条消息暂时不允许给消费者消费,需要再次对该消息发送comfirm 确认后才可消费
  1. service_A生产者发送一条半消息到mq,
  2. 如果mq返回成功,则证明通信正常,service_A 可以继续执行本地事务,如果发送半消息失败,则service_A 什么也不干
  3. 本地执行业务代码,提交本地事务。
  4. 提交事务有可能成功或者失败
  5. 如果本地事务失败,则发送fail信息到mq,删除前面发送的half massage,comsumer 消费不到该消息;如果本地事务成功,则发送success消息到mq,mq 则发送该消息给comsumer service_B 进行消费。
  6. 第5步有可能因为通信等原因没有发送success或者fail给mq, mq会定时扫描broker里面的half message,如果超时没有受到确认消息,则回回调Service_A 接口, 接口需要根据本地数据库实际情况,确认事务是否成功,然后在发送确认消息到mq。
  7. 如果消息发送成功,mq将尽最大努力将该消息发送给service_B 进行消费。

优点:实现简单,容易落地。
缺点:代码耦合度高,侵入性大,需要些回调代码。同时需要考虑mq的消息积压问题。

总结

综上,目前分布式事务中,seata是最合适的选择,实现简单,代码无侵入,学习成本低,性能高,可直接内嵌到微服务架构里面来

你可能感兴趣的:(分布式专题)