分布式事务⽅案怎么调研选型?TCC、ataAT、最终⼀致性事务的原理和优缺
点都有什么?
初中物理怎么学
分布式事务⼀直是微服务等分布式系统不得不⾯对的难题。⽬前主流的解决⽅案有以下⼏种。
1. 基于阿⾥巴巴开源的ata AT模式分布式事务框架
2. TCC 三段式提交事务⽅案(业界⼀般使⽤ByteTCC框架)
3. 基于RocketMq 消息中间件实现最终⼀致性事务
下⾯基于这三种⽅式进⾏原理剖析对⽐选型以及各⾃的优缺点⽐较
⼀、Seata
TC:事务协调器。控制全局事务的开启,提交回滚。
TM:事务管理器,负责定义事务的边界,负责发起开启⼀个全局事务、提交事务,回滚事务。例如上图中。rver-A调⽤rver-B和rver-C。则在rver-A开启全局事务。
RM:资源管理器。事务执⾏者,控制本分⽀事务的提交和回滚。
原理过程:
1. TM像TC发起全局事务,TC⽣成⼀个全局的唯⼀事务XID,返回给TM,
2. xid可以在服务调⽤的上下⽂中进⾏传播。
3. RM 向TC注册分⽀事务,并且纳⼊该xid全局事务的范围内
4. TM向TC发起全局事务的提交和回滚
5. TC控制各个RM事务的提交和回滚
AT 两段式提交
上左图:阶段⼀提交成功,释放本地事务锁,阶段⼆什么也不做,因此ata⽐传统的两段式XA模式性能要好很多,真实业务中⼤部分事务也是成功的,没必要全程占有锁。
上右图:只有当第⼆阶段全局回滚时才两个阶段都占有锁。
提交和回滚
阶段⼀:
备注:这⾥的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种情况:
全局事务成功:
打扫卫生英文第⼆阶段,如果全局事务成功,则直接删除undo_log对应的回滚数据⽇志即可,不需要再持有本地事务锁,所以Seata性能相对较⾼全局事务失败:
如果全局事务失败,则查找对应的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实现最终⼀致性
half message: 半消息,也就是消息发送到rocket mq broker后,这条消息暂时不允许给消费者消费,需要再次对该消息发送comfirm 确认后才可消费
1. rvice_A⽣产者发送⼀条半消息到mq,
2. 如果mq返回成功,则证明通信正常,rvice_A 可以继续执⾏本地事务,如果发送半消息失败,则rvice_A 什么也不⼲
3. 本地执⾏业务代码,提交本地事务。
4. 提交事务有可能成功或者失败
5. 如果本地事务失败,则发送fail信息到mq,删除前⾯发送的half massage,comsumer 消费不到该消息;如果本地事务成功,则发送
success消息到mq,mq 则发送该消息给comsumer rvice_B 进⾏消费。
6. 第5步有可能因为通信等原因没有发送success或者fail给mq, mq会定时扫描broker⾥⾯的half message,如果超时没有受到确认消炒土豆丝的家常做法
息,则回回调Service_A 接⼝, 接⼝需要根据本地数据库实际情况,确认事务是否成功,然后在发送确认消息到mq。
7. 如果消息发送成功,mq将尽最⼤努⼒将该消息发送给rvice_B 进⾏消费。