今天遇到了一个线上的重大bug,小程序拼团业务,例如当一个团金额达到10000元时,这个团就表示拼团成功,但是在金额马上到达10000元瞬间,多个用户同时下单,支付完成微信后台调取callback接口,因为当成团的那一刻,给当前团的用户发送奖励,线程1正在发送奖励,还没有完成时,线程2又过来了,线程三,线程四同时过来,就会循环执行发送奖励代码,造成线上多个给用户返利,解决方案:
把跟用户的交互不能交给用户来完成,要交给系统处理,写一个定时方法,定时查看哪个团拼成功了,然后给已拼成功但是还未发奖励的用户发送奖励,完美解决
在这里插入代码片
//已成团
if (group.equals(1)) {
//发放奖励
List<ActivityGroupRechargeOrder> list = activityGroupRechargeOrderDaoService.query()
.eq("activity_group_recharge_team_id", team.getId())
.eq("status", 1)
.eq("send", 0)
.list();
Map<String, Person> personMap = personDaoService.getMapByIds(list.stream().map(ActivityGroupRechargeOrder::getPersonId).collect(Collectors.toList()));
for (ActivityGroupRechargeOrder vo : list) {
//占比
Double percent = NumberUtil.round(vo.getAmount().doubleValue() / team.getRecharge().doubleValue(), 5, RoundingMode.HALF_DOWN).doubleValue();
//应到金额
Double amount = NumberUtil.round(team.getReceipt() * percent, 0, RoundingMode.HALF_DOWN).doubleValue();
//修改用户余额
personDaoService.update()
.setSql(" balance = balance + " + amount)
.eq("id", vo.getPersonId())
.update();
PersonBalanceLog log = new PersonBalanceLog();
log.setId(IdUtil.objectId());
log.setPersonId(vo.getPersonId());
log.setOpera("+");
log.setType(1);
log.setAmount(amount);
log.setTitle("拼团成功,团编号" + team.getOrderNo() + ",到账金额:" + log.getAmount() + "元");
log.setSurplus(0.0);
personBalanceLogDaoService.save(log);
//已发放奖励
activityGroupRechargeOrderDaoService.update()
.set("send", 1)
.eq("id", vo.getId())
.update();
if (personMap.containsKey(vo.getPersonId())) {
Person person = personMap.get(vo.getPersonId());
WeChat.Message.mini("user")
.openid(person.getOpenId())
.template("X1UaO1H_iR3QVoB_Bar1C63nhWpEFtTv_VkWI9FmEP8")
.option("thing3", "成功")
.option("thing4", "拼团金额已到账~")
.send();
}
}
}