分布式事务的解决方案

分布式事务的演变过程

1、传统项目,两个项目在一个系统里,不存在远程调用,不存在分布式事务问题。

2、分布式,应用和数据库都进行拆分,基于同步调用的方式,来实现接口调用。

    控制事务的实现方式:基于XA协议的两段式提交或三段式提交

XA是一个分布式事务协议,是数据库层的一个协议,XA中大致分为两部分:事务管理器和本地资源管理器(数据库)。

缺点:非常耗时,性能低。

优点:安全性高,事务一致性好。

适用场景:对安全性要求高,并发量低的场景

总结:XA协议比较简单,而且一旦商用数据库实现了XA协议,使用分布式事务的成本也比较低。但是XA也有致命的缺点,那就是性能不理想,特别是在交易下单链路,往往并发量很高,XA无法满足高并发场景。需要注意的是:XA目前在商业数据库(oracle)支持的比较理想,在mysql数据库中支持的不太理想,mysql的XA实现,没有记录prepare阶段日志,主备切换会导致主库和备库数据不一致。许多nosql也没有支持XA,这让XA的应用场景相较而言比较狭隘。

3、基于消息中间件

当同步调用的方式不能满足高并发用户请求量时,需要使用异步调用方式。以下以用户发起一笔从支付宝到余额宝的转账为例。

可能出现的问题:

(1)消息丢失问题。余额宝拿到消息后进行消费操作数据库时出问题,会导致消息被消费了,给MQ进行了确认并删除了消息,但是没有进行实际处理。

(2)重复消费问题。如果回调失败,通过message,又会继续往MQ里发送消息。

解决:

a、在支付宝数据库添加一个message存根表,保存流水信息。当支付宝扣款时生成一条记录。然后有个定时线程来循环message表,当发现message表有一个unconfirm(没有被余额宝消费)的记录时,就会将消息发送到MQ,供余额宝消费。余额宝消费成功后将unconfirm修改为confirm。

b、如果余额宝down机,且时间比较长,那么MQ中的消息一直未被消费,定时线程就会一直扫描,然后往MQ发送未消费的消息,这样会有很多条消息,等余额宝服务正常之后,全部消费,造成重复消费的问题。

c、在余额宝服务中,也添加一个message表,当消息消费成功后,也会往message表生产一条记录,且messageId与支付宝的messageId一致。这样当余额宝每从消息队列拿到一条待消费的消息时,就根据messageId向message查一下有没有记录,如果有记录就不做操作直接返回。如果没有记录,就继续处理,进行余额宝的增款操作。

最终流程:

a、当支付宝扣款成功后,往message表插入一条unconfirm记录。

b、当时线程不停的扫描message表,当扫描到unconfirm记录时,将这条信息插入MQ供余额宝消费。

c、余额宝拉取到这条消息进行消费时,首先根据messageId向它自己的message表进行查询。

d、如果有记录,直接返回,如果没记录,进行增款操作。

e、增款操作成功之后,向MQ插入一条消息,代表余额宝消费成功。

f、支付宝拉取MQ中的消息,获取到余额宝添加的消费成功消息后,将message表的status字段由uncoonfirm改为confirm。代表消费完成。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值