记得上下班打卡 | git大法好,push需谨慎

Commit 71941971 authored by wangyifan's avatar wangyifan

福袋功能- 修复并发问题

parent 3abddaf0
......@@ -20,7 +20,7 @@ public class KylinBrands implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Integer mid;
private Long mid;
/**
* 品牌ID
......
......@@ -20,7 +20,7 @@ public class KylinLuckyBag implements Serializable, Cloneable{
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Integer mid;
private Long mid;
/**
* 福袋ID
......
......@@ -18,7 +18,7 @@ public class KylinLuckyBagActivity implements Serializable, Cloneable{
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Integer mid;
private Long mid;
/**
* 福袋活动ID
......
......@@ -18,7 +18,7 @@ public class KylinRewardCode implements Serializable, Cloneable{
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Integer mid;
private Long mid;
/**
* 兑换码
......
......@@ -19,7 +19,7 @@ public class KylinRewardUser implements Serializable, Cloneable{
private static final long serialVersionUID = 1L;
@TableId(value = "mid", type = IdType.AUTO)
private Integer mid;
private Long mid;
/**
* 用户ID
......
......@@ -2,6 +2,15 @@ package com.liquidnet.service.kylin.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.liquidnet.service.kylin.entity.KylinRewardCode;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
public interface KylinRewardCodeMapper extends BaseMapper<KylinRewardCode> {
@Select("SELECT * FROM kylin_reward_code WHERE mid = #{mid}")
KylinRewardCode selectByMid(@Param("mid") Long mid);
@Update("update kylin_reward_code set state=#{state} where mid=#{mid}")
int updateByMid(@Param("mid") Long mid, @Param("state") int state);
}
......@@ -152,60 +152,62 @@ public class KylinLuckyBagServiceImpl implements IKylinLuckyBagService {
* @return
*/
private List<KylinRewardUser> getRandomRewardCode(OrderDetailsVo vo, String luckyBagId) {
String lockKey = KylinRedisConst.LUCKY_BAG_CODE_LOCK + luckyBagId;
try {
// 1. 获取分布式锁,防止并发问题
boolean locked = redisUtil.lock(lockKey, 1, 30);
if (!locked) {
log.info("[getRandomRewardCode] 未获取到分布式锁.");
return Collections.emptyList();
}
final int limitTotal = vo.getOrderTicketVo().getNumber();
if (limitTotal <= 0) {
log.error("[getRandomRewardCode] 用户订单购买数量错误, orderId: {}.", vo.getOrderTicketVo().getOrderTicketsId());
return Collections.emptyList();
}
final int limitTotal = vo.getOrderTicketVo().getNumber();
final KylinOrderTicketVo orderTicketVo = vo.getOrderTicketVo();
final String lockKey = KylinRedisConst.LUCKY_BAG_CODE_LOCK + luckyBagId;
boolean locked = redisUtil.lock(lockKey, 1, 30);
if (!locked) {
log.info("[getRandomRewardCode] 未获取到分布式锁.");
return Collections.emptyList();
}
if (limitTotal <= 0) {
log.error("[getRandomRewardCode] 用户订单购买数量错误, orderId: {}.", orderTicketVo.getOrderTicketsId());
return Collections.emptyList();
}
LambdaQueryWrapper<KylinRewardCode> lambdaQueryWrapper = new QueryWrapper<KylinRewardCode>().lambda()
.eq(KylinRewardCode::getLuckyBagId, luckyBagId)
.eq(KylinRewardCode::getState, 1)
.last(true, " limit " + limitTotal);
//2. 搜索未分配的兑换码
List<KylinRewardCode> rewardCodes = kylinRewardCodeMapper.selectList(lambdaQueryWrapper);
LambdaQueryWrapper<KylinRewardCode> lambdaQueryWrapper = new QueryWrapper<KylinRewardCode>().lambda()
.eq(KylinRewardCode::getLuckyBagId, luckyBagId)
.eq(KylinRewardCode::getState, 1)
// .last(true, "ORDER BY RAND() limit " + limitTotal); // 随机搜索
.last(true, " limit " + limitTotal);
//2. 搜索兑换码
List<KylinRewardCode> rewardCodes = kylinRewardCodeMapper.selectList(lambdaQueryWrapper);
if (rewardCodes.size() < limitTotal) {
log.error("[getRandomRewardCode] 兑换码不足, luckyBagId: {}, need total: {}.", luckyBagId, limitTotal);
// 报警
String msg = String.format("福袋ID [%s] 兑换码不足,请及时补充.", luckyBagId);
iFeishuBotService.sendTextMessage(msg);
return Collections.emptyList();
}
if (rewardCodes.isEmpty() || rewardCodes.size() < limitTotal) {
log.error("[getRandomRewardCode] 兑换码不足, luckyBagId: {}, need total: {}.", luckyBagId, limitTotal);
// 报警
String msg = String.format("福袋ID [%s] 兑换码不足,请及时补充.", luckyBagId);
iFeishuBotService.sendTextMessage(msg);
return Collections.emptyList();
}
//3. 写入
final KylinOrderTicketVo orderTicketVo = vo.getOrderTicketVo();
List<KylinRewardUser> rewardUsers = new ArrayList<>(limitTotal);
//3. 写入
List<KylinRewardUser> rewardUsers = new ArrayList<>(limitTotal);
try {
for (int i = 0; i < rewardCodes.size(); i++) {
KylinRewardCode rewardCode = rewardCodes.get(i);
rewardCode.setState(0);
int updateResult = kylinRewardCodeMapper.updateById(rewardCode);
if (updateResult > 0) {
KylinRewardUser user = buildRewardUser(orderTicketVo.getUserId(),
orderTicketVo.getOrderTicketsId(),
luckyBagId,
orderTicketVo.getEntitiesVoList().get(i).getOrderTicketEntitiesId(),
rewardCode.getCode());
kylinRewardUserMapper.insert(user);
rewardUsers.add(user);
log.info("[getRandomRewardCode] 兑换码分配成功, luckyBagId: {}, orderId: {}, code: {}.", luckyBagId, orderTicketVo.getOrderTicketsId(), rewardCode.getCode());
} else {
log.error("[getRandomRewardCode] 兑换码分配失败, luckyBagId: {}, orderId: {}.", luckyBagId, orderTicketVo.getOrderTicketsId());
// 报警
String msg = String.format("福袋ID [%s] 分配兑换码失败:用户ID [%s] 的订单ID [%s] 已分配了 [%s] 个,应分配 [%s] 个。",
luckyBagId, orderTicketVo.getUserId(), orderTicketVo.getOrderTicketsId(), rewardUsers.size(), limitTotal);
iFeishuBotService.sendTextMessage(msg);
KylinRewardCode lockedRewardCode = rewardCodes.get(i);
KylinRewardUser rewardUser = buildRewardUser(orderTicketVo.getUserId(),
orderTicketVo.getOrderTicketsId(),
luckyBagId,
orderTicketVo.getEntitiesVoList().get(i).getOrderTicketEntitiesId(),
lockedRewardCode.getCode());
int inserted = kylinRewardUserMapper.insert(rewardUser);
if (inserted > 0) {
// 将兑换码状态更新为已领取
int updateResult = kylinRewardCodeMapper.updateByMid(lockedRewardCode.getMid(), 0);
if (updateResult <= 0) {
log.error("[getRandomRewardCode] 修改兑换码状态失败, luckyBagId: {}, orderId: {}, code: {}.",
luckyBagId, orderTicketVo.getOrderTicketsId(), lockedRewardCode.getCode());
// 报警
String msg = String.format("修改兑换码状态失败:福袋ID: [%s], 用户ID: [%s], 订单ID: [%s], code: [%s]。",
luckyBagId, orderTicketVo.getUserId(), orderTicketVo.getOrderTicketsId(), lockedRewardCode.getCode());
iFeishuBotService.sendTextMessage(msg);
} else {
log.info("[getRandomRewardCode] 兑换码分配成功, luckyBagId: {}, orderId: {}, code: {}.",
luckyBagId, orderTicketVo.getOrderTicketsId(), lockedRewardCode.getCode());
rewardUsers.add(rewardUser);
}
}
}
return rewardUsers;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment