如何避免“扣减了积分,但是没有成功创建订单”? - 分布式事务相关

2022-01-15 21:51:44 +08:00
 JasonLaw

假设现在有商城和会员两个服务,用户在商城使用积分购买商品,但是用户的积分是存储在会员服务的。

现在的流程如下:

扣减积分发生在会员服务中,创建订单及修改订单状态为已支付发生在商城服务中,所以会出现“扣减了积分,但是没有成功创建订单”这种情况。

应该怎么解决这个问题呢?

4084 次点击
所在节点    程序员
23 条回复
nonoyang
2022-01-15 21:55:57 +08:00
这应该是很典型的分布式事务吧,补偿机制?
qza1212
2022-01-15 21:59:03 +08:00
感觉顺序就错了,应该先创建订单,然后再扣积分
JasonLaw
2022-01-15 22:06:50 +08:00
@qza1212 #2 创建订单包含了扣减积分,扣减积分的结果会影响订单的状态。
qza1212
2022-01-15 22:21:14 +08:00
@JasonLaw #3 了解了,两个方案吧,要么把积分扣减和将订单改为已支付这两个操作写到一个事务里,这里必然要用分布式事务。
或者也可以在扣减积分记录里记下订单 ID ,这样查询订单是未支付的时候需要再查一下积分记录,查看是否真的扣减成功。
dzdh
2022-01-15 22:24:42 +08:00
经典事物补偿
LinSP
2022-01-15 22:25:49 +08:00
用分布式事务感觉重了,扣减积分和订单对应一下就行,订单失败了就补偿下
dzdh
2022-01-15 22:26:02 +08:00
不会出现"扣减了积分,但是没有成功创建订单"的情况。
只会出现事物超时下单失败,积分重新+回去。
gancl
2022-01-15 23:28:49 +08:00
可以积分先锁住,创建订单失败则解锁积分;创建订单成功则用掉锁住的积分吗?
akira
2022-01-15 23:55:47 +08:00
扣减 改为冻结,订单成功后才真的扣
clf
2022-01-16 01:37:26 +08:00
创建订单-订单中就包含了需要消耗的积分和会员 ID

扣减积分-扣减记录中包含了订单的 ID

当订单和积分均存在时,这两条数据才是订单创建成功+积分扣除成功;如果不存在对应数据,用户端两条数据均不会显示,并触发回滚机制(触发回滚后提醒用户失败原因)
Rocketer
2022-01-16 02:14:34 +08:00
我记得在某银行的积分商城里见过这个场景,积分记录里有创建订单扣减和取消订单(其实是订单失败)增加两条记录
levelworm
2022-01-16 03:06:53 +08:00
@LinSP 请教一下,这有似乎个问题,如果补偿的时候商品卖完了怎么办?感觉还是强制要求确认订单成功之后再扣减积分用户体验比较好?不过如果扣减不成功,补偿也会出现万一用户下单多次导致补偿的时候无分可扣,还得取消多余的订单。。。是不是我想的太多了。。。
levelworm
2022-01-16 03:08:14 +08:00
@akira 我感觉这个还蛮好,同时避免了用户连续下单导致积分来不及扣。看来冻结是必要的。
winglight2016
2022-01-16 09:27:15 +08:00
@JasonLaw 不一定非要用分布式事务来解决。一是可以用工作流来处理,二是可以用 MQ 半事务,分布式事务个人觉得不可靠,是最后的选择。
751327
2022-01-16 17:38:21 +08:00
本地消息表、事务消息、tcc 方案、Seata AT
beitayongguo
2022-01-17 11:50:47 +08:00
业务上创建订单强依赖扣减积分 TCC 可能好点。 如果不强依赖,那搞成异步 MQ 吧~ 本地消息表事务消息都可以
julyclyde
2022-01-17 12:28:43 +08:00
其实积分场景用事后对账机制挺好的
TUNGH
2022-01-17 12:38:11 +08:00
我说一个解决方案吧,先创建订单,订单状态是中间态,比如支付中或者处理中,然后去扣积分,扣除成功就改订单支付成功状态,扣除失败就改订单状态为创建失败,失败原因是积分不足.当然,如果是积分和现金一起支付,那必然先锁住积分再创建订单.
eijnix
2022-01-17 16:36:09 +08:00
巧了 我就是某电商公司做会员的。。
我们是这样做的,积分表有个预扣字段,首先进行预扣,并记录需要下订单的商品的唯一 id ,再进行下订单,下订单失败则进行积分回滚,否则就进行积分正式扣除(核对下订单的商品的唯一 id )
当然这里会发一些 kafka 给重试服务,是为了防止服务 down 掉的情况
eijnix
2022-01-17 16:41:49 +08:00
你现在的流程的话已经跟商城服务有太多的耦合了,而且用户的入口似乎是商城那边,做法可能跟我这个就不太一样了,有点像我们会员中的 offer 服务,我们用的是 tcc 方案

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/828494

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX