首页
注册
登录
liangliplusss 最近的时间轴更新
liangliplusss
V2EX 第 583090 号会员,加入于 2022-05-28 14:47:48 +08:00
liangliplusss
提问
技术话题
好玩
工作信息
交易信息
城市相关
liangliplusss 最近回复了
4 天前
回复了
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 ), 扣减成功发送消息到消息队列更新数据库。
»
liangliplusss 创建的更多回复
关于
·
帮助文档
·
博客
·
API
·
FAQ
·
实用小工具
·
2873 人在线
最高记录 6679
·
Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 11ms ·
UTC 13:20
·
PVG 21:20
·
LAX 05:20
·
JFK 08:20
Developed with
CodeLauncher
♥ Do have faith in what you're doing.