首页
注册
登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请
登录
V2EX
›
liangliplusss
›
全部回复第 1 页 / 共 1 页
回复总数
1
25 天前
回复了
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
·
实用小工具
·
2735 人在线
最高记录 6679
·
Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 9ms ·
UTC 12:25
·
PVG 20:25
·
LAX 04:25
·
JFK 07:25
Developed with
CodeLauncher
♥ Do have faith in what you're doing.