Browse Source

feat:问题修改

master^2
管理员 7 months ago
parent
commit
49efdbac66
  1. 7
      nla-common/src/main/java/cn/nla/common/interceptor/LoginInterceptor.java
  2. 23
      nla-coupon-service/src/main/java/cn/nla/coupon/controller/CouponController.java
  3. 16
      nla-coupon-service/src/main/java/cn/nla/coupon/mq/CouponMQListener.java
  4. 29
      nla-coupon-service/src/main/java/cn/nla/coupon/service/impl/CouponServiceImpl.java

7
nla-common/src/main/java/cn/nla/common/interceptor/LoginInterceptor.java

@ -21,7 +21,10 @@ import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
public static ThreadLocal<LoginUser> threadLocal = new ThreadLocal<>();
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
threadLocal.remove();
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
try {
@ -57,4 +60,6 @@ public class LoginInterceptor implements HandlerInterceptor {
CommonUtil.sendJsonMessage(response, JsonData.buildError("token不存在,请重新登录"));
return false;
}
}

23
nla-coupon-service/src/main/java/cn/nla/coupon/controller/CouponController.java

@ -1,12 +1,19 @@
package cn.nla.coupon.controller;
import cn.nla.common.enums.BizCodeEnum;
import cn.nla.common.enums.CouponCategoryEnum;
import cn.nla.common.exception.BizException;
import cn.nla.common.interceptor.LoginInterceptor;
import cn.nla.common.model.LoginUser;
import cn.nla.common.util.JsonData;
import cn.nla.coupon.model.request.NewUserCouponRequest;
import cn.nla.coupon.service.CouponService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -20,12 +27,16 @@ import javax.annotation.Resource;
* @since 2024-08-08
*/
@Api(tags = "优惠券控制器")
@Slf4j
@RestController
@RequestMapping("/cop/coupon/v1")
public class CouponController {
@Resource
private CouponService couponService;
@Resource
private RedissonClient redissonClient;
@ApiOperation("分页查询优惠券")
@GetMapping("page_coupon")
public JsonData pageCouponList(
@ -40,7 +51,17 @@ public class CouponController {
@ApiOperation("领取优惠券")
@GetMapping("/add/promotion/{coupon_id}")
public JsonData addPromotionCoupon(@ApiParam(value = "优惠券id", required = true) @PathVariable("coupon_id") long couponId) {
return couponService.addCoupon(couponId, CouponCategoryEnum.NEW_USER);
LoginUser loginUser = LoginInterceptor.threadLocal.get();
String lockKey = "lock:coupon:" + couponId+":"+loginUser.getId();
RLock rLock = redissonClient.getLock(lockKey);
//多个线程进入,会阻塞等待释放锁
rLock.lock();
try {
return couponService.addCoupon(couponId, CouponCategoryEnum.NEW_USER);
} finally {
rLock.unlock();
log.info("解锁成功");
}
}
/**
* 新用户注册发放优惠券接口

16
nla-coupon-service/src/main/java/cn/nla/coupon/mq/CouponMQListener.java

@ -4,6 +4,7 @@ import cn.nla.common.model.CouponRecordMessage;
import cn.nla.coupon.service.CouponRecordService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
@ -11,6 +12,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
@Slf4j
@Component
@ -20,8 +22,8 @@ public class CouponMQListener {
@Resource
private CouponRecordService couponRecordService;
// @Resource
// private RedissonClient redissonClient;
@Resource
private RedissonClient redissonClient;
/**
* 重复消费-幂等性
@ -34,8 +36,8 @@ public class CouponMQListener {
@RabbitHandler
public void releaseCouponRecord(CouponRecordMessage recordMessage, Message message, Channel channel) throws IOException {
//防止同个解锁任务并发进入;如果是串行消费不用加锁;加锁有利也有弊,看项目业务逻辑而定
//Lock lock = redissonClient.getLock("lock:coupon_record_release:"+recordMessage.getTaskId());
//lock.lock();
Lock lock = redissonClient.getLock("lock:coupon_record_release:"+recordMessage.getTaskId());
lock.lock();
log.info("监听到消息:releaseCouponRecord消息内容:{}", recordMessage);
long msgTag = message.getMessageProperties().getDeliveryTag();
boolean flag = couponRecordService.releaseCouponRecord(recordMessage);
@ -51,9 +53,9 @@ public class CouponMQListener {
log.error("释放优惠券记录异常:{},msg:{}", e, recordMessage);
channel.basicReject(msgTag, true);
}
// finally {
// lock.unlock();
// }
finally {
lock.unlock();
}
}

29
nla-coupon-service/src/main/java/cn/nla/coupon/service/impl/CouponServiceImpl.java

@ -50,8 +50,8 @@ import java.util.stream.Collectors;
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity> implements CouponService {
@Resource
private RedissonClient redissonClient;
// @Resource
// private RedissonClient redissonClient;
@Resource
private CouponRecordMapper couponRecordMapper;
@ -78,12 +78,12 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity> i
@Override
public JsonData addCoupon(Long couponId, CouponCategoryEnum category) {
LoginUser loginUser = LoginInterceptor.threadLocal.get();
String lockKey = "lock:coupon:" + couponId;
RLock rLock = redissonClient.getLock(lockKey);
//多个线程进入,会阻塞等待释放锁
rLock.lock();
// String lockKey = "lock:coupon:" + couponId+":"+loginUser.getId();
// RLock rLock = redissonClient.getLock(lockKey);
// //多个线程进入,会阻塞等待释放锁
// rLock.lock();
log.info("领劵接口加锁成功:{}", Thread.currentThread().getId());
try {
// try {
CouponEntity coupon = baseMapper.selectOne(
Wrappers.<CouponEntity>lambdaQuery()
.eq(CouponEntity::getId, couponId).eq(CouponEntity::getCategory, category.name()));
@ -108,10 +108,17 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity> i
log.warn("发放优惠券失败:{},⽤户:{}", coupon, loginUser);
throw new BizException(BizCodeEnum.COUPON_NO_STOCK);
}
} finally {
rLock.unlock();
log.info("解锁成功");
}
// } finally {
// rLock.unlock();
// log.info("解锁成功");
// }
// try {
// TimeUnit.SECONDS.sleep(10L);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
return JsonData.buildSuccess();
}

Loading…
Cancel
Save