Commit fd7d53f8 authored by zhangfeng's avatar zhangfeng

兑换礼品换锁

parent 06d7e08e
...@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.reward.api.reward; ...@@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.reward.api.reward;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.generator.SnowflakeGenerator; import cn.hutool.core.lang.generator.SnowflakeGenerator;
import cn.iocoder.yudao.framework.redis.helper.RedisDistributedLock; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi; import cn.iocoder.yudao.module.member.api.score.MemberUserScoreApi;
import cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO; import cn.iocoder.yudao.module.member.api.score.dto.MemberUserScoreOperateReqDTO;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
...@@ -18,12 +18,18 @@ import cn.iocoder.yudao.module.reward.dal.mysql.reward.RewardMapper; ...@@ -18,12 +18,18 @@ import cn.iocoder.yudao.module.reward.dal.mysql.reward.RewardMapper;
import cn.iocoder.yudao.module.reward.enums.RewardRedeemStatusEnum; import cn.iocoder.yudao.module.reward.enums.RewardRedeemStatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*; import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.GET_LOCK_FAILED; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.GET_LOCK_FAILED;
...@@ -42,7 +48,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -42,7 +48,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
@Resource @Resource
private MemberUserApi memberUserApi; private MemberUserApi memberUserApi;
@Resource @Resource
private RedisDistributedLock redisDistributedLock; private RedissonClient redissonClient;
@Resource @Resource
private MemberUserScoreApi memberUserScoreApi; private MemberUserScoreApi memberUserScoreApi;
@Resource @Resource
...@@ -71,10 +77,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -71,10 +77,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
throw exception(REWARD_PICK_METHOD_NOT_ALLOW_CREATE); throw exception(REWARD_PICK_METHOD_NOT_ALLOW_CREATE);
} }
verifyMemberUser(redeemRewardReqVO, rewardDO); verifyMemberUser(redeemRewardReqVO, rewardDO);
boolean lock = false; String lockKey = "reward:redeem:lock:" + redeemRewardReqVO.getRewardId();
RLock lock = redissonClient.getLock(lockKey);
try { try {
lock = redisDistributedLock.lock("reward:redeem:lock:" + redeemRewardReqVO.getRewardId()); if (!lock.tryLock(2, 10, TimeUnit.SECONDS)) {
if (!lock) {
throw exception(GET_LOCK_FAILED); throw exception(GET_LOCK_FAILED);
} }
// 添加兑换记录 // 添加兑换记录
...@@ -83,10 +89,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -83,10 +89,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
updateMemberScore(redeemRewardReqVO, rewardDO, redeemId); updateMemberScore(redeemRewardReqVO, rewardDO, redeemId);
// 更新礼品 // 更新礼品
redeemReward(rewardDO, redeemRewardReqVO.getRewardCount()); redeemReward(rewardDO, redeemRewardReqVO.getRewardCount());
} catch (Exception e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw exception(GET_LOCK_FAILED);
} finally { } finally {
redisDistributedLock.releaseLock("reward:redeem:lock:" + redeemRewardReqVO.getRewardId()); lock.unlock();
} }
return null; return null;
} }
...@@ -118,7 +124,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -118,7 +124,7 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
RewardRedeemDO rewardRedeemDO = BeanUtil.copyProperties(redeemRewardReqVO, RewardRedeemDO.class); RewardRedeemDO rewardRedeemDO = BeanUtil.copyProperties(redeemRewardReqVO, RewardRedeemDO.class);
rewardRedeemDO.setId(snowflakeGenerator.next()); rewardRedeemDO.setId(snowflakeGenerator.next());
rewardRedeemDO.setStatus(RewardRedeemStatusEnum.REDEEMING.getValue()); rewardRedeemDO.setStatus(RewardRedeemStatusEnum.REDEEMING.getValue());
rewardRedeemDO.setScoreCount(redeemRewardReqVO.getRewardCount()* rewardDO.getPointsRequire()); rewardRedeemDO.setScoreCount(redeemRewardReqVO.getRewardCount() * rewardDO.getPointsRequire());
rewardRedeemMapper.insert(rewardRedeemDO); rewardRedeemMapper.insert(rewardRedeemDO);
return rewardRedeemDO.getId(); return rewardRedeemDO.getId();
} }
...@@ -156,10 +162,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -156,10 +162,10 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
throw exception(REWARD_COUNT_NOT_ENOUGH); throw exception(REWARD_COUNT_NOT_ENOUGH);
} }
} }
boolean lock = false; String lockKey = "reward:redeem:lock:" + rewardId;
RLock lock = redissonClient.getLock(lockKey);
try { try {
lock = redisDistributedLock.lock("reward:redeem:lock:" + rewardId); if (!lock.tryLock(2, 10, TimeUnit.SECONDS)) {
if (!lock) {
throw exception(GET_LOCK_FAILED); throw exception(GET_LOCK_FAILED);
} }
for (RedeemRewardReqVO redeemRewardReqVO : redeemRewardReqVOList) { for (RedeemRewardReqVO redeemRewardReqVO : redeemRewardReqVOList) {
...@@ -170,11 +176,13 @@ public class RedeemRewardApiImpl implements RedeemRewardApi { ...@@ -170,11 +176,13 @@ public class RedeemRewardApiImpl implements RedeemRewardApi {
// 更新礼品 // 更新礼品
redeemReward(rewardDO, redeemRewardReqVO.getRewardCount()); redeemReward(rewardDO, redeemRewardReqVO.getRewardCount());
} }
} catch (Exception e) { } catch (ServiceException e) {
log.error("redeem reward exception",e); log.error("batch redeem rewards exception", e);
throw e; throw e;
} catch (InterruptedException e) {
throw exception(GET_LOCK_FAILED);
} finally { } finally {
redisDistributedLock.releaseLock("reward:redeem:lock:" + rewardId); lock.unlock();
} }
return null; return null;
} }
......
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