分布式--2分布式事务

系列文章目录

分布式–1概述CAP和Base
分布式–2分布式事务
分布式–3分布式一致性算法
分布式-4集群
分布式–5服务限流算法
分布式–6分布式id
分布式–7性能压测
分布式–8日志链路跟踪
分布式-9分布式锁|redis锁的几种实现

一、本地事务

参考 https://blog.csdn.net/qq_35841637/article/details/114482254

二、分布式事务

1、原因

分布式系统间各种问题:宕机、网络不稳定

本地事务无法满足需求:
1)远程服务假失败: 远程服务其实成功了,由于网络故障等没有返回 导致:订单回滚,库存却扣减
2)远程服务执行完成,下面的其他方法出现问题 导致:已执行的远程请求,肯定不能回滚

三、分布式事务解决方案

1、两阶段提交协议(2PC)

1)定义

两阶段提交系统中,存在一个节点作为协调者,其他节点为参与者。
所有的节点都采用预写式日志。日志记录不会丢失。
所有的节点不会永久性的宕机,即使宕机后仍可以恢复。
第一阶段:事务管理器要求每个涉及到事务的数据库预提交此操作,并反映是否可以提交.
第二阶段:根据第一阶段的反馈,事务协调器要求每个数据库提交数据,或者回滚数据。
在这里插入图片描述

2)缺点:

事务管理器为单点,故障以后整个数据库集群无法使用
在执行过程中,所有参与事务的节点都是事务独占状态,当有参与者占用公共资源时,那么其他第三方节点对公共资源的访问会被阻塞。
第二阶段中,假设协调者发出了事务commit的通知仅被一部分参与者所收到并执行,其余的参与者则因为没有收到通知一直处于阻塞状态,这时候就产生了数据的不一致性。

3)变形–seata

2、三阶段提交协议(3PC)

1)定义

为解决两阶段提交协议中,公共资源占用堵塞的问题,三阶段提交协议中协调者和参与者都引入了超时机制,然后把两阶段提交协议里的第一个阶段拆分为两步:先询问(CanCommit),再锁资源(PreCommit),再最后提交(DoCommit)。

2)阶段

CanCommit:
协调者向参与者发送Commit请求,参与节点反映是否可以调节。
PreCommit:
根据CanCommit响应情况有以下两种执行情况。
如果所有的参与节点返回Yes,则进行事务的预执行:协调者向参与者发送PreCommit请求,使参与者进入Prepare阶段。并向协调者反馈ACk。
如果任意一个节点返回了NO,或者等待超时进进行中断操作。则协调者向所有的参与者发送abort请求,参与者执行abort请求放弃事务的执行。
DoCommit:
阶段根据PreCommit的响应也有两种执行情况。
如果协调者收到所有参与者的ACk响应,则发送doCommit请求,所有的参与者提交事务释放资源,并向协调者反馈ACK响应。
如果协调者没有到所有参与者的ACK响应,则会执行中断事务
在这里插入图片描述

3)缺点:

在DoCommit阶段中,假设协调者发出了事务commit的通知仅被一部分参与者所收到并执行,其余的参与者则因为没有收到通知一直处于阻塞状态,这时候就产生了数据的不一致性。

3、TCC

在这里插入图片描述
很多框架都实现了TCC,我们只需要把自己的代码业务拆成三部分,放在对应的是三个方法里,框架就可以帮我们按时机执行。
相当于三阶段的手动版
1)定义
TCC是支付宝提出的分布式事务解决方案,每个分布式事务的参与者都需要实现3个接口:try、confirm、cancel。

Try阶段:
调用方调用各个服务的 try 接口,各个服务执行资源检查和锁定,看自己是否有能力完成,如果允许,则锁定资源.
Confirm阶段:
各个服务的 try 接口都返回了 yes,则进入提交阶段,调用方调用各个服务的 confirm 接口,各个服务对 try 阶段锁定的资源进行处理。如果 try 阶段有一方返回了 no,或者超时,调用方调用各个服务的 cancel 接口,释放锁定的资源
Cancel阶段:
取消执行,释放Try阶段预留的业务资源
Confirm阶段和Cancel阶段是互斥的,只能进行一个,而且都是幂等性的,允许失败重试。
2)优点

1. TCC解决了跨服务的业务操作原子性问题,可以让应用自己定义数据库操作的粒度,降低锁冲突,提高系统的业务吞吐量。
2. TCC的每一阶段都由业务自己控制,避免了长事务,提高了性能。

3)缺点

1. 业务侵入性强:业务逻辑必须都要实现Try,Confirm,Cancel三个操作
异常情况

4)空回滚

现象是 try 没被执行,就调用了 cancel:调用 try 时出现异常,try 接口实际没有被调用,自然没有返回 yes,那么会按照正常流程进入第2阶段,调用 cancel 接口,这就形成了空回滚。
解决方法:让 cancel 能够识别出这是一个空回滚,可以记录事务执行状态,cancel 中判断 try 是否执行了。

5)重复调用

提交阶段异常时可能会重复调用 confirm 和 cancel,所以要实现幂等,保证多次执行效果一致。
解决方法:记录事务执行状态,如果执行过了,就不再执行。

6)悬挂

现象是先执行了 cancel,后执行的 try,造成资源没人释放:调用 try 时网络拥堵超时,被认为失败,然后调用 cancel,这时事务相当于结束了,但后来网络好点之后 try 开始执行了,锁定了相关资源,因为事务已经结束,confirm、cancel 都不会再调用了,就造成资源悬挂,无法释放。
解决方法:还是记录事务执行状态,try 执行时判断 cancel 是否执行了。

4、可靠消息+最终一致性

1)背景

在大规模高并发服务化系统中,一个功能被拆分成多个具有单一功能的元功能,一个流程会有多个系统的多个元功能组合实现,如果使用两阶段提交协议和三阶段提交协议,确实能解决系统间一致性问题,除了这两个协议带来的自身的问题,这些协议的实现比较复杂、成本比较高,最重要的是性能并不好,相比来看,TCC协议更简单、容易实现,但是TCC协议由于每个事务都需要执行Try,再执行Confirm,略微显得臃肿,因此,在现实的系统中,底线要求仅仅需要能达到最终一致性,而不需要实现专业的、复杂的一致性协议,实现最终一致性有一些非常有效的、简单粗暴的模式

2)最终一致性的几种做法

详见 分布式–3分布式一致性算法

3)实战

利用MQ延时队列,实现高并发下的定时任务,最终一致解除订单或者解除库存锁定。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
1)下单之后,锁定库存。
2)发送一个消息给交换机,key为lock,经交换机发给延时队列
3)延时队列50分钟后经过交换机,路由到relase
4)relase被监听消费后,检查订单状态是否要解锁,业务处理
上图还有个库存解锁模块,是可以手动或其他情况触发解锁(也可以其他业务直接放入relase队列进行解锁)
代码:MyRabbitConifg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值