# 7、高并发抢红包示例(非事务版本)
'use strict';
module.exports = {
/**
* 高并发抢红包示例
* @url db_api/sys/concurrent 前端调用的url参数地址
*/
main: async (event) => {
let { data = {}, userInfo, util, filterResponse, originalParam } = event;
let { customUtil, config, pubFun, vk, db, _ } = util;
let { uid } = data;
let res = { code: 0, msg: "" };
// 业务逻辑开始-----------------------------------------------------------
let money = 1; // 每次抢红包的金额
res.num = await vk.baseDao.update({
dbName:"vk-test", // 红包测试表
whereJson:{
_id:_id, // 红包id,
money: _.gte(money), // 判断当前红包金额必须>=要扣除的金额
receive_uid: _.nin([uid]), // 只有我没领过才可以领
},
dataJson:{
money: _.inc(money*-1), // 减当前红包金额
receive_uid: _.push(uid), // 将当前登录用户的id写入该红包,防止重复领取
}
});
// 利用update + where 形成数据库乐观锁达到控制高并发下不会扣成负数。
if(res.num <= 0){
return { code: -1, msg: "未抢到红包,您已抢过或红包已抢完!" };
}
// 给用户加余额
await vk.baseDao.update({
dbName:"vk-test-balance", // 用户余额测试表
whereJson:{
user_id : uid
},
dataJson:{
balance: _.inc(money) // 加抢到的当前红包金额
}
});
res.msg = `恭喜,抢到了${money}元红包`;
// 业务逻辑结束-----------------------------------------------------------
return res;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47