php高并发余额正确_高并发下怎么做余额扣减?
php⾼并发余额正确_⾼并发下怎么做余额扣减?
取决于是计费⾼并发,还是⽤户⾼并发。
前者是同⼀账户,同时并发多个计费请求,导致余额变化,好像⼀个银⾏账户,多个银⾏卡,同时刷卡买东西;后者是多个⽤户在线,⽤各⾃的账户消费,互不影响。
看题设,更像是前者,就基于计费⾼并发来讨论。
曾遇到过⼀个需求,每个账户每秒有⼏百次计费请求,要求很简单,
1,⼜快⼜准。
2,余额不为负。
同⼀个字段被并发修改,很⾃然会想到⽤lock,但系统有很多其他业务逻辑,计费只是很⼩的⼀部分,要⾜够的轻,就开始考虑尽量⽆锁的⽅案。⼤概思路如下,
记录持久化,余额内存化。
余额是充值和消费的结果,在不断变化,但充值和消费是记录,⼀旦发⽣,不会再变,某时某刻花了10
怎么查银行卡余额
块,这条记录产⽣了,就永远不会变。这类记录持久化,放在DB⾥。
有了记录,可以在任何时刻,重建余额。这个余额是否需要持久化,不⼀定,还要考虑是否存在过期等。我们虽选择持久化余额,但不加锁,因为读写不发⽣在DB上,⽽是在内存⾥。
内存⾥,⽤户有两个值,⼀个是余额,⼀个是花费。⽤户消费时,余额不变,花费增加。两个问题,
为什不直接减余额呢?
不改余额,就可以保证内存⾥的余额始终和DB中的⼀致,⽽内存⾥花费始终和消费记录⼀致。⽤户的实时余额 = 余额 - 花费。
内存计费是否加锁?
余额不为负,意味着要先确认实时余额 > 所需花费,才能消费,check, then update,这并不是atomic 的,意味着存在 race condition,计费函数是不是⼀定要加锁呢?
如果先查余额,再扣钱,的确要加锁;但也可以先扣钱,再查余额,若⼩于0,则把钱加回来,返回计费失败,阻⽌消费,这样就不⽤加锁了。当然,余额和花费应选Atomic数据类型。
这样⾼并发下的余额扣减就变得⾮常的轻,对 performance ⼏乎没有影响,也满⾜了⼜快⼜准的需求。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。