批量支付 1000 笔以上运单

52 天前
 loszhang
我们客户现在有个需求,需要支持一次请求可以发起 1000 笔以上运单的支付,主要集中在月底,大概有 6 万以上的运单。目前我们支持的最大数量是 200 笔,是同步请求,就是一次请求,会把运单的状态修改为支付处理中,修改钱包,记录运单状态的其他数据,大概每笔运单需要修改或者新增 5 张表,然后向 mq 写入一条支付消息,用于向支付平台发起支付的请求,这是一笔运单需要做的,最后会把这 200 笔运单结果返回给前端,实际的支付会由 mq 去处理。现在如果要处理 1000 笔以上的运单,肯定不能再用同步请求,主要就是把这 1000 笔运单记录下来,修改状态,不能让客户将这 1000 笔运单再发起一次支付请求。不知道大家有没有好的处理方案。
1863 次点击
所在节点    Java
33 条回复
loszhang
52 天前
@dong568789 如果是同步更新状态,就不会出现用户会重复提交的问题。如果是异步更新状态,就会出现。
ftsland
52 天前
楼主的需求 redis 挺合适的啊, 根据客户 id 记录到 set 里, 你是怕 redis 的数据意外挂了没了吧, 同时把运单数据记录到日志里呗
loszhang
52 天前
@perbugwei 我换成 foreach 插入,1000 笔,300 毫秒。那我就同步记录下请求中的运单 id ,查询时过滤掉已经记录的运单,这样就不会再重复发起。
offswitch
52 天前
6w id 也不是很多,1000 笔订单,作为一次批处理,用户支付一次,记录这 1000 笔订单的 id ,甚至都不用逐个修改状态,如果重复提交已处理的订单 id ,后台直接抛出错误。


前端设计上,考虑一下新开一个批量处理订单,这几万个订单一次性返回,一页展示 1000 行,这一页处理完成,前端过滤掉这一页,显示下一页。
offswitch
52 天前
至于后面的修改订单状态,放到 mq 中一个个修改成处理中,之后订单一个个入队,走正常订单处理流程
offswitch
52 天前
前端页面展示状态,后端你可以直接从 redis 中取订单的状态(批量提交的订单 id 一定要记录到数据库里面),如果有这个订单 id ,说明订单正在处理中,不用实际修改数据库中每一个订单的状态
loszhang
52 天前
@offswitch 我主要是一开始不太确定,应该如何去更改这 1000 笔运单的状态,如果同步修改,可能会耗时比较久,给用户的感受不太好。我刚才换了中批量插入的方式,很快了。
让前端设计下,这个一般前端是不太想参与的,😄。
loszhang
52 天前
感谢大家的回复,我目前选择的方式是,用户发起批量支付时,同步将运单的 id 写入新表中,然后返给前端处理中的结果。前端查询时,我会过滤掉已经记录的运单,这样就不会造成用户重复发起。
因为一开始我担心批量修改和插入会比较耗时,我试下了循环调用 insert 插入,确实比较费时,1000 条 40 秒,然后换成 foreach 插入,1000 条 300 毫秒。所以选择同步去记录运单。
后续如果还有其他问题,也会更新,感谢。
Satella
52 天前
你们这个客户,应该是做网络货运的吧,说不定还带点违规那种
lanfeng579
52 天前
@loszhang #28 你这个肯定不能循环 insert 啊 你循环插入 网络 IO 次数太多了,建议是接口进入的时候 你就去加分布式锁,不然的话 会有并发问题,撞上了同时点的快点,可能你还没存进去 他又发起了支付请求,这种 最好多测一下
zhkn
52 天前
循环调用 insert1000 次也不应该是 40 秒吧,循环中还做了其他处理吗
Jack66
52 天前
mq 处理没问题,注意数据一致性问题。好奇的是你们怎么自动支付,支付有这种功能吗,即使有的话,支付应该提供 api 批量支付,然后响应参数。
yc8332
52 天前
@loszhang 加锁。之后你可以队列去更新数据库或者插入数据库。。尽量用批量更新/插入,时间少很多。

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

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

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

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

© 2021 V2EX