海量并发场景下,如何实现分布式事务

本文介绍了在分布式环境下如何保证事务的C(一致性)属性,包括两阶段提交协议的同步阻塞问题及三阶段提交的改进,以及eBay采用的基于消息中间件的最终一致性解决方案。
摘要由CSDN通过智能技术生成

什么是分布式事务

首先得知道,正常一个事务要满足ACID原则,但是实际上,海量并发环境下是分库分表的,需要协调多个系统才能完成一个事务。那么怎么设计策略来保证事务的ACID中的C一致性呢?接下来介绍主要的两种思想。

强一致性(集中式)

两阶段提交协议

这是最朴素的解决方式,将事务分为两个阶段,分别是投票和提交。有一个全局管理者——协调者,还有若干参与者(即发起事务请求的)

投票

协调者会向事务的参与者发起执行操作的CanCommit请求,并等待参与者的响应。参与者收到请求后会执行自己的事务操作,然后记录日志,但不提交事务。执行成功向协调者发Yes,反之No

提交

协调者看是不是所有参与者都是Yes,是的话向参与者发送DoCommit,参与者收到后会提交事务并释放资源(锁)。
假设协调者发现不是所有参与者都Yes了,那就向所有参与者发送DoAbort,此时发Yes的参与者就回滚。
最后所有参与者接收到不论是DoCommit还是DoAbort都会回复协调者HaveCommitted

不足

协调者寄了,系统就崩了。
网络出问题了,假设协调者发DoCommit不是所有参与者都受到了,那系统数据就不一致了。
所有参与者都是事务阻塞型的,无法高并发。

三阶段提交协议

为了解决二阶段提交的同步阻塞和数据不一致问题,三阶段提交引入了超时机制和准备阶段。

CanCommit

与二阶段一样,只不过参与者接收到协调者发来的CanCommit后只判断能不能正常执行,而不真的执行。判断能就返回Yes,不能就No

PreCommit

如果所有参与者都给协调者发的Yes,那么协调者就会发送PreCommit给所有参与者。参与者执行事务,并记录日志,并返回ACK给协调者。
假设有参与者给协调者发No,或者超时了,那协调者就会给所有参与者发Abort指令。参与者收到Abort或者超时就中断事务执行。

DoCommit

若协调者接收到所有参与者发送的Ack响应,则向所有参与者发送DoCommit消息。参与者接收到DoCommit消息之后,正式提交事务。完成事务提交之后,释放所有锁住的资源,并向协调者发送Ack响应。协调者接收到所有参与者的Ack响应之后,完成事务。
假设有参与者没返回Ack或者协调者等待超时,协调者向所有参与者发送Abort请求。参与者接收到Abort消息之后,利用其在PreCommit阶段记录的Undo信息执行事务的回滚操作,释放所有锁住的资源,并向协调者发送Ack消息。协调者接收到参与者反馈的Ack消息之后,执行事务的中断,并结束事务。

最终一致性(分布式)

eBay

基于分布式消息的最终一致性方案,其引入了一个消息中间件(Message Queue,MQ,消息队列)。以网购下单为例,假设用户A在某电商平台下了一个订单,需要支付50元,发现自己的账户余额共150元,就使用余额支付,支付成功之后,订单状态修改为支付成功,然后通知仓库发货。过程如下所示:
在这里插入图片描述
那对于eBay而言,处理流程是:
在这里插入图片描述
每次执行成功一个指令,都在消息队列(消息中间件)里持久化一条消息。假设失败就删除消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值