liangliplusss 最近的时间轴更新
liangliplusss

liangliplusss

V2EX 第 583090 号会员,加入于 2022-05-28 14:47:48 +08:00
liangliplusss 最近回复了
31 天前
回复了 hhhhhh123 创建的主题 程序员 高并发下怎么做余额扣减?
两个方案
方案一: 悲观锁
consume(var accountId,var amount) {
//先查询余额
"select accountId,balance from xxx where accountId = $accountId for update";
//计算
$new_balance = $old_balance - $amount;
update xxx balance = $new_balance where accountId = $accountId
}

方案二: 乐观锁
consume(var accountId,var amount) {
flag = false,retires = 3
// CAS + 重试
while(!flag && retries > 0) {
flag = consume0(accountId,amount);
retries--;
}

}

boolean consume0(var accountId,var amount) {
//先查询余额(只是查询不加锁)
"select accountId,balance from xxx where accountId = $accountId";
//计算
$new_balance = $old_balance - $amount;
row = update xxx balance = $new_balance where accountId = $accountId and balance = $old_balance
return row == 1;
}

备选方案:(高并发,单个用户消费并发超过 1000 )缓存 + 消息中间件,
用户消费操作是扣减缓存中余额(注意这里原子性查询和扣减两个动作,例如 redis 可以使用 lua ), 扣减成功发送消息到消息队列更新数据库。
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3322 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 10ms · UTC 11:34 · PVG 19:34 · LAX 03:34 · JFK 06:34
Developed with CodeLauncher
♥ Do have faith in what you're doing.