请问钱包提现有审核,余额应该怎么设计
我现在有一个需求,要设计一个结算钱包,目前有两张表,一张记录收入,一张记录提现
两张表里都有余额这个字段,那么现在问题来了,每次有收入的时候,会sum一次所有收入,然后再sum一次所有成功提现,然后总收入减总支出,就是当前的余额,对吧
但是提现就有点麻烦,因为提现要后台审核,那么就会记录的时候余额本来是400,提现10元,但是因为没有审核,实际余额还是400,这个时候我是记录400,还是390呢?如果记录400,细心的用户又会看着疑惑,如果记录390,要是提现失败了,是不是又要重新更新这条记录
所以想问问大家,这种提现待审核的钱包,要怎么设计,另外同时收入和提现的操作,是用悲观锁吗?
高认可度评论:
这里要引入另一个概念:
在途帐
(transit) ,在用户端可以叫做锁定金额之类的。 这个在途帐指的是申请了提现,但还没有提现成功。(入帐在途暂不讨论)。 用户的余额(balance) = 收入 - 支出 ,用户的锁定金额为 在途帐。用户下次
可提现金额
为 用户余额 - 在途帐 ( balance - transit)。 若提现成功,记入提现支出,冲销在途帐。此时 支出增加,在途减少。 若提现失败,则不记提现支出,冲销在途帐。或者,更好的办法是 找个会计,咨询一下。
提现的属于冻结资金
这里要引入另一个概念:
在途帐
(transit) ,在用户端可以叫做锁定金额之类的。 这个在途帐指的是申请了提现,但还没有提现成功。(入帐在途暂不讨论)。 用户的余额(balance) = 收入 - 支出 ,用户的锁定金额为 在途帐。用户下次
可提现金额
为 用户余额 - 在途帐 ( balance - transit)。 若提现成功,记入提现支出,冲销在途帐。此时 支出增加,在途减少。 若提现失败,则不记提现支出,冲销在途帐。或者,更好的办法是 找个会计,咨询一下。
再加个字段。操作某个用户变动金额的,加redis 的锁和乐观锁
是设计复杂了。提现也是从余额减出 只是这部分钱没有直接到用户手中 中间经过审核表。审核通过则生成余额变动记录,审核不通过则退回余额。大概的表设计是,用户账户资产表:余额、所有支出、所有收入;提现表:前余额、金额、后余额、绑定余额变动记录;资产变化表:前余额、变动余额、后余额。资产变化表的 model 中封装两个方法:增加、减少,都使用事务。
这里有一个同样的问题。 问答:冻结余额 数据库怎么设计比较好?
直接悲观锁,余额变动这些没什么好说的,在mysql用主键查询加锁就是个行锁,对于性能几乎没有影响
借鉴下微信股票账户的隔日提现机制
我一般处理是提现就扣掉余额,然后如果提现失败,生成一条新的记录,然后平账
模型:
用户钱包:所属用户,钱包标记,冻结金额,可用金额,余额(虚拟列)
交易流水:所属钱包,交易金额,交易类型,交易后钱包余额,时间
体现&充值记录:所属钱包,变更金额,变更类型,变更后余额,变更状态,变更时间
用户提现后,减少可用余额,增加冻结金额,提现失败则原来回滚
流水只做记录,排查
是不是想复杂了?
钱包一张表,关联用户,记录余额,冻结金额之类的。
收入和支出一张表,叫做流水表。
扣除, 审核未通过或其他情况时返还
冻结, 我们就是冻结表 ,冻结的金额是不允许用的
加一个冻结字段,余额持续扣钱,审核失败再返回到钱包
多加一个字段吧,冻结或者体现中(如果只有体现业务的话),这样计算的时候,减掉这个字段的金额就行了。