nuomiphp
正在加载…
请使用更现代的浏览器并启用 JavaScript 以获得最佳浏览体验。
加载论坛时出错,请强制刷新页面重试。
高并发下怎么做余额扣减?
opengps
一楼说出了核心,虽然银行类业务用户多,但是架不住最大的客户操作完一个交易也是需要时间的,这时间不会导致并发
hhhhhh123
Jooooooooo
那库存这种问题 应该怎么解决?
Jooooooooo
hhhhhh123
库存的高并发扣减算是比较成熟的东西了, 随便一搜很多的比如可以搞多层拦截, 如果你只卖 10 个东西, 要是有 1w 人来抢, 那绝大多数流量没有必要到后端, 反正总是能把东西卖出去的. 前端和网关可以直接随机丢弃流量, 流量到了后端后, 可以再加上 MQ 排队和缓存, 最终再到数据库里行锁扣库存.还有手段比如把库存分散到多行数据上, 随机挑一行扣
brust
hhhhhh123
#8库存的话如果是热点 SKU 可以分段锁 比如有 1w 个库存 可以分成 10 个 1000 出来
ElmerZhang
如果并发不会很高的话不用在数据库上加锁
1. 要扣的钱为 A ,先查 amount 当前值为 B ,代码中判断 B >= A
2. 然后执行 update xxx set amount = amount - A where amount = B
3. 执行看影响行数,如果为 0 ,重新从第 1 步执行
一般只需要重试一次。
CEBBCAT
ElmerZhang
dongtingyue
coderxy
看三位的回答中好像没有提到事务,不用事务的话遇到意外停机怎么办呢?或者是我理解错了
8520ccc
ElmerZhang
update xxx set amount = amount - A where amount = B where amount-A>0
codehz
ElmerZhang
那不如直接 update xxx set amount = amount - A where amount > A (
hhhhhh123
ElmerZhang
我理解 第一步和第二步 ,第三部不是特别理解, 为啥只递归一次?
dongtingyue
update xxxxx set xxxx where 余额>xx 余额 用 innodb 本身就有行锁,失败返回异常,这点时间肯定要等的
coderxy
乐观锁就够了,修改时判断一下余额与你之前查到的余额是否一致。
git00ll
一锁 二查 三更新
jobmailcn
CEBBCAT
同时更新多个才要事务,例如给一个人加余额,另一个人减余额。
CEBBCAT
jobmailcn
是的。我看楼主这个 case 就是需要一边扣钱,一边发放什么东西。
awanganddong
https://www.51cto.com/article/720873.html
并发扣款,如何保证一致性
沈剑 大佬的文章可以看看
richangfan
update users set balance = balance - 1 where user_id = 123 and balance >= 1;
只在余额大于 1 时扣除用户 123 的 1 块钱
orzwalker111
richangfan
假设网关、框架重试,会多扣款,解决手段:1 、悲观锁,使用分布式锁2 、乐观锁,使用 CAS ,select 得到的 balance 作为 update 的 where 条件,并添加 ver 条件解决 ABA 问题
hhhhhh123
vanillacloud
codehz
8520ccc
richangfan
如果这样的话, 同时有俩个 一个扣款 10 块 一个扣款 5 块。 这样只会执行其中的一个余额。 另外一个就不会执行。 我觉得 8 楼的 第三个条件挺好, 但是递归次数 又不好拿捏。
louisliu813
orzwalker111
是的,我们也是使用 cas ,更新时判断 version ,如果被其他事物更新到 version + 1 了,就 select 新的 balance 和 version 出来,然后基于新 version 做判断,新 balance 做更新。
xuanbg
不要做无意义的事情,15 楼的方法可以很好的解决 OP 你的这个问题。
rqrq
try {
BEGIN;
SELECT balance FROM userinfo WHERE user_id = xxx FOR UPDATE;
逻辑判断,有问题就 throw Exception
UPDATE userinfo...
COMIT;
} catch {
ROLLBACK;
}
rqrq
BEGIN 写在 try 外面。
yogogo
事务加行锁,扣款交易可以先入库,再用异步任务按顺序执行交易扣款。有些第三方代扣服务就是这样设计的
dingyaguang117
乐观锁即可
下一页 »