# 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
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