从储值卡(会员卡)充值业务看分布式事务的设计.pdfVIP

从储值卡(会员卡)充值业务看分布式事务的设计.pdf

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多

从储值卡(会员卡)充值业务看分布式事务的设计

公司有一项储值卡充值业务:客户在微信公众号开通储值卡服务,

通过微信支付往卡里面充值,充值成功后客户可收到消息通知,并进

行消费。

看起来是一项很简单的业务,最初我们储值卡团队的实现也确实

很简单。我们看看最初的实现:

相信聪明的你一眼就能看出问题:

1.压根没有考虑分布式事务一致性,比如第12步根本没有考虑卡

系统充值失败的情况该如何处理,而是默认其一定能成功;

2.大部分的处理都是放在前端业务系统(除了这里的公众号系统,

还有POS机系统,而POS机是通过调公众号系统接口来实现的);

3.第4步直接下单,第5步直接调微信支付,压根没有跟卡系统

有任何通信:这里默认用户的充值行为一定是合法的;

4.在微信的支付回调中(第10步往后),是先处理一系列业务逻

辑,最后才调充值接口,这里也是默认卡充值一定能成功;

看到这里你可能会大呼开发人员是不是没长脑子?

实际情况是,这个版本的开发是几年前的事情了,那时候公司还

是创业早期,第一目标是尽快上线能用,而且客户量没有那么大,虽

然中间也出现过一些数据不一致的情况,也都通过人工处理了事了。

随着公司业务的发展,用户量越来越大,而且还要和第三方合作

(储值卡作为一种支付方式提供给第三方使用),问题出现得也越来

越频繁,不得不将这块提上重构议程。

那么,针对上面提的几点问题,我们大体能想到如下重构项:

1.将充值业务逻辑从前端系统剥离,做成单独的服务;

2.在下单前,先调一下卡系统接口,检查用户的充值行为是否合

法,避免后面不必要的麻烦;

3.在支付回调中,处理充值失败的场景;

初步设计如下:

这里我们重点讨论下对第14步(卡充值接口返回结果)的处理:

1.如果返回充值成功,那万事大吉,该干嘛干嘛;

2.如果失败呢?可能的处理方式如下:

1.继续重试,最多重试3次,如果成功了,万事大吉;

2.如果上面重试还是失败,那么调微信退款,并将订单状态

改成充值失败;

骚年你等等!

你说什么?重试失败了就去退款?

实践中,远程调用失败的一个很大原因是网络超时(而超时的很

大原因又是对方负载过高),而面对超时,我们是不知道对方到底有

没有处理成功的,万一这边把钱退掉了,那边又充值成功咋办?(我

们是SaaS服务商,这时真正的损失方是我们的商户,而商户无疑会找

我们索赔的)

一种方案是:

在多次重试失败后发起微信退款之前,先调卡系统查询接口,如

果查询结果是充值成功,则不退款,继续后续流程,否则发起退款;

该方案在实际中也基本行不通,因为如果那段时间网络有问题或

者对方服务器负载高,查询也有很大概率失败,或者就算查成功了并

返回充值记录不存在,也有可能之前调的充值接口还在跑(比如处于

锁等待状态)。

有人可能会说,没关系啊,就算退款后充值成功了,那后面通过

人工或者系统发现数据问题再处理掉不就行了吗?

问题在于,如果在发现问题之前,用户已经从卡上消费掉了呢

(比如用户当场冲1000然后立马消费掉,这在我们实际场景中是经常

发生的,因为很多商户会搞充值活动,比如冲1000送200)?把卡余

额扣成负数?(这不是我杜撰的,在我们老储值卡系统就出现过几次

这种情况,当时是直接由公司给商户赔钱)

因此,关键在于,当充值中心不知道卡系统有无充值成功的情况

下,需要内部假定充值成功了。

最终,我们决定用定时任务来解决。在微信支付回调中,如果多

次调卡充值接口失败,我们不发起退款,也不进行后续流程,而是在

数据库中写入一条异常记录,然后结束本次处理。

在定时任务中(比如10分钟一次),我们取出那些异常记录,调

卡系统相关接口核对最终状态,如果充值成功了,则补充执行充值成

功的后续流程,否则发起微信退款,并执行其他充值失败流程(如改

订单状态,给用户发通知、回调业务系统等)。

为了防止钱退了后卡又充值成功,定时任务中只处理1小时前的

数据。

另一个隐藏的问题是,在前面的充值流程中,直到微信支付回调,

卡系统都没有关于这次充值行为的任何记录。这可能会导致后续一系

列问题,其中一个

文档评论(0)

159****0673 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档