分布式事务的解决方案

时间:2022-03-01作者:klpeng分类:IT综合浏览:253评论:0

分布式事务的演变过程

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。代表消费完成。

打赏
文章版权声明:除非注明,否则均为彭超的博客原创文章,转载或复制请以超链接形式并注明出处。
相关推荐

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

猜你喜欢