项目回顾:一个简单的充值码库存管理系统

背景

回顾一下去年 6 月左右做的一个库存管理系统。

需求

我们是做一个游戏充值平台,最早我们是分销,给别的充值平台引流,最终的支付和发货(即充值到账)都是在合作伙伴系统里完成的。

这回第一次上线自己的售卖系统,先从最简单的充值码做起,因为不需要太多后台对接,无论我们还是游戏商家做起来都容易。

第一步:从商家获取充值码

当时是从商家拿了一个 Excel 表,表里存了很多充值码。需要把这些充值码录入到后台,并且加密。

第二步:需要能在平台上售卖充值码

这个很好理解。而且比较简单,下一个单只能买一个充值码。

第三步:后台管理系统

一个关键问题是,在充值码快卖光时要即时补货,所以要有存货不足提醒功能。

实现

实现方面,有几个可圈可点的地方:

防止重复售卖、重复发货

重复售卖是指多个订单买到了同一份充值码;重复发货是指一个订单(只买一份充值码)买到了多个充值码。

一般来说,为了保证发货的一致性(或者说发货指令的幂等性),需要使用数据库的事务/锁。一开始我打算用事务,后来一个有经验的同事说,事务这东西能少用就少用,因为调试起来麻烦,还容易造成死锁之类的问题。

我忘了是谁想出来的了,反正最终的解决方案既没用到事务也没用到锁!实现如下:

  • 首先,需要把充值码那张表的“订单编号”字段设置为 unique key;
  • 每次为订单寻找匹配充值码时,直接执行 Update transaction_id=new_transaction_id where transaction_id=null limit 1

如果能执行成功,说明:

  • 这份充值码没有卖出过(避免重复售卖),不然不会有 where transaction_id=null
  • 同一个订单并没有发货过(避免重复发货),因为 transaction_id 有 unique key 的限制,如果两个充值码记录填同样的 transaction_id 会报错;

反之,如果执行失败,则根据错误类型可以判断:要么是没有空余的充值码了,要么是该订单已经发过货了。

防止超售

超售的问题是,用户在支付之前看到还有库存,就去支付了,可是在支付期间库存卖完了!

当然,解决这个问题的最简单方法是,进入支付流程之前先锁定一个库存,类似于去吃饭前先预留座位。但这样做的问题是,很多用户过了很久也不支付,放弃购买了,这样的话就会有很多库存被白白锁定,造成浪费。

所以最终我们采取的方案是,并没有锁定,但会预留一些“缓冲库存”,比方说 100 个。在只剩下 100 个的时候就停止售卖了,这 100 个就留给那些仍然没有完成支付的用户,如果他们真的完成支付了也不会没有库存发给他们。

其实理想情况下这个数字应该不是固定的,而是根据处在支付流程中的用户数量按比例调整的。那就留给之后再改进吧。

邮件系统

卖给用户的充值码需要邮件发送给他们,库存不足了也需要邮件提醒运营同学。我们一波三折,最终搞定了公司内部的发邮件服务。

性能

我在的那会儿,性能还不是主要问题,因为卖得最好的时候不过每天 1 万多单,算下来 QPS 应该在个位数。

(当时在支付模块,有个前同事设计数据库时没给订单编号加索引,导致数据量大了之后开始变得特别慢,后来发现并修复了。)

小结

大致就是这么回事,先写这么多吧。设计数据库挺有意思的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值