分布式事务

基础理论

分布式事务是为了解决微服务架构下的事务问题

CAP理论

C是一致性,A是可用性,P是分区容错性,在一致性上有强一致性,软一致性和最终一致性,CAP三者只能选择其二,一般是选择AP

BASE理论

BA是基本可用,S是软状态,E是最终一致性

NPC问题

因为微服务系统不在同一个机器上,NPC可能会导致分布式事务问题

  • N
    -网络延迟
  • P
    因为垃圾回收等可能的原因导致的进程问题
  • C
    因为不同的机器在不同的环境下,可能因为温度导致石英钟不准确,发生的事务跳跃等等

分布式事务的问题

悬挂,幂等,空补偿

  • 幂等
    由于N,P问题进行重试,所以对幂等必须处理,对GID和事务ID进行记录处理幂等
  • 空补偿
    因为Cancel快于Try,因此对于Cancel行为不能进行,所以得查try是否执行了,查看try是否记录,如果有记录不能cancel
  • 悬挂
    是由于try慢于Cancel,因为cancel是空补偿,因此try执行的时候必须不能做,因此常看cancel是否来过,如果cancel来过不能执行try。

分布式事务框架

解决分布式事务有两种方式,一种是引入第三组件,如dtm或则Seata (Seata 只支持Java,因此go里使用dtm)
一般来说,分布式事务是先查后改,但是先查后改的情况还是可能发生空补偿,悬挂等问题,因此dtm采用插入代替
在try的时候,插入一个gid-branchid-try操作
cancel的时候,先插入gid-branchid-try操作,再插入gid-branchid-cancel操作

  • 情况1:
    对于空回滚问题,如果cancel的时候gid-branchid-try插入成功,那么说明是空回滚,cancel失败;
  • 情况2:
    对于悬挂的时候,如果gid-branchid-try插入失败,那么说明cancel执行过,则不进行try
  • 情况3:
    如果是正常的回滚,先插入gid-branchid-try,然后回滚先插入gid-branchid-try失败,但是gid-branchid-cancel插入成功,则正常回滚;
    至于幂等问题,会发展成情况1,2,3,无需详细考虑

常见的分布式事务解决方案

  • XA
    因为资源会锁定,因此只能用于并发量不大的事务
  • TCC
    Try-Cancel-Commit
    基于BASE理论的中间状态,比如我们转账的时候,在表里插入一个预加金额和预扣金额,这也事务的状态处于中间状态,等所有的分布式事务都准备好后,再执行金额的真正的运算,适用于对一致性要求比较高的事务
    同样的,对性能损耗比较大,也要回滚处理
  • SAGA
    将长事务拆分成短事务,就是一个个分布式事务连续提交,如果有一个有问题,那么就一个个回滚
    拆分成短事务后,对资源的占用和并发就上去了
  • 基于消息服务的最终一致性
    这种最大优势是吞吐量以及不需要回滚,百分之90的生产都是基于消息服务解决最终一致性

基于消息服务的最终一致性

在这里插入图片描述
消息服务是如下流程,主要讨论它是如何在分布式环境下的NP问题保证最终一致性

  • 步骤1失败
    直接返回错误
  • 步骤2失败
    没有执行分布式事务,直接返回失败
  • 步骤3失败
    那么有定时任务1去轮询检查状态,如果消息为init的消息,并且查看redis里是否有标记,如果有标记,则将init改为send
  • 步骤4失败
    有定时2任务轮询检查状态,如果消息为send,那么会发送消息给消息队列,消息队列会处理幂等问题
    如果定时任务发送次数非常高,则日志报警人工介入
  • 步骤5失败
    无论是消息队列发送给消息服务,还是自己消费失败,定时任务2会一直发送消息,保证一定消费成功

实战

SAGA

go+dtm

消息服务

go+KFK+asynq

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值