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

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

@ -1,12 +1,19 @@
package cn.nla.coupon.controller; package cn.nla.coupon.controller;
import cn.nla.common.enums.BizCodeEnum;
import cn.nla.common.enums.CouponCategoryEnum; 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.common.util.JsonData;
import cn.nla.coupon.model.request.NewUserCouponRequest; import cn.nla.coupon.model.request.NewUserCouponRequest;
import cn.nla.coupon.service.CouponService; import cn.nla.coupon.service.CouponService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; 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 org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -20,12 +27,16 @@ import javax.annotation.Resource;
* @since 2024-08-08 * @since 2024-08-08
*/ */
@Api(tags = "优惠券控制器") @Api(tags = "优惠券控制器")
@Slf4j
@RestController @RestController
@RequestMapping("/cop/coupon/v1") @RequestMapping("/cop/coupon/v1")
public class CouponController { public class CouponController {
@Resource @Resource
private CouponService couponService; private CouponService couponService;
@Resource
private RedissonClient redissonClient;
@ApiOperation("分页查询优惠券") @ApiOperation("分页查询优惠券")
@GetMapping("page_coupon") @GetMapping("page_coupon")
public JsonData pageCouponList( public JsonData pageCouponList(
@ -40,7 +51,17 @@ public class CouponController {
@ApiOperation("领取优惠券") @ApiOperation("领取优惠券")
@GetMapping("/add/promotion/{coupon_id}") @GetMapping("/add/promotion/{coupon_id}")
public JsonData addPromotionCoupon(@ApiParam(value = "优惠券id", required = true) @PathVariable("coupon_id") long couponId) { 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 cn.nla.coupon.service.CouponRecordService;
import com.rabbitmq.client.Channel; import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.core.Message; import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
@ -11,6 +12,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.locks.Lock;
@Slf4j @Slf4j
@Component @Component
@ -20,8 +22,8 @@ public class CouponMQListener {
@Resource @Resource
private CouponRecordService couponRecordService; private CouponRecordService couponRecordService;
// @Resource @Resource
// private RedissonClient redissonClient; private RedissonClient redissonClient;
/** /**
* 重复消费-幂等性 * 重复消费-幂等性
@ -34,8 +36,8 @@ public class CouponMQListener {
@RabbitHandler @RabbitHandler
public void releaseCouponRecord(CouponRecordMessage recordMessage, Message message, Channel channel) throws IOException { public void releaseCouponRecord(CouponRecordMessage recordMessage, Message message, Channel channel) throws IOException {
//防止同个解锁任务并发进入;如果是串行消费不用加锁;加锁有利也有弊,看项目业务逻辑而定 //防止同个解锁任务并发进入;如果是串行消费不用加锁;加锁有利也有弊,看项目业务逻辑而定
//Lock lock = redissonClient.getLock("lock:coupon_record_release:"+recordMessage.getTaskId()); Lock lock = redissonClient.getLock("lock:coupon_record_release:"+recordMessage.getTaskId());
//lock.lock(); lock.lock();
log.info("监听到消息:releaseCouponRecord消息内容:{}", recordMessage); log.info("监听到消息:releaseCouponRecord消息内容:{}", recordMessage);
long msgTag = message.getMessageProperties().getDeliveryTag(); long msgTag = message.getMessageProperties().getDeliveryTag();
boolean flag = couponRecordService.releaseCouponRecord(recordMessage); boolean flag = couponRecordService.releaseCouponRecord(recordMessage);
@ -51,9 +53,9 @@ public class CouponMQListener {
log.error("释放优惠券记录异常:{},msg:{}", e, recordMessage); log.error("释放优惠券记录异常:{},msg:{}", e, recordMessage);
channel.basicReject(msgTag, true); channel.basicReject(msgTag, true);
} }
// finally { finally {
// lock.unlock(); 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 @Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity> implements CouponService { public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity> implements CouponService {
@Resource // @Resource
private RedissonClient redissonClient; // private RedissonClient redissonClient;
@Resource @Resource
private CouponRecordMapper couponRecordMapper; private CouponRecordMapper couponRecordMapper;
@ -78,12 +78,12 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, CouponEntity> i
@Override @Override
public JsonData addCoupon(Long couponId, CouponCategoryEnum category) { public JsonData addCoupon(Long couponId, CouponCategoryEnum category) {
LoginUser loginUser = LoginInterceptor.threadLocal.get(); LoginUser loginUser = LoginInterceptor.threadLocal.get();
String lockKey = "lock:coupon:" + couponId; // String lockKey = "lock:coupon:" + couponId+":"+loginUser.getId();
RLock rLock = redissonClient.getLock(lockKey); // RLock rLock = redissonClient.getLock(lockKey);
//多个线程进入,会阻塞等待释放锁 // //多个线程进入,会阻塞等待释放锁
rLock.lock(); // rLock.lock();
log.info("领劵接口加锁成功:{}", Thread.currentThread().getId()); log.info("领劵接口加锁成功:{}", Thread.currentThread().getId());
try { // try {
CouponEntity coupon = baseMapper.selectOne( CouponEntity coupon = baseMapper.selectOne(
Wrappers.<CouponEntity>lambdaQuery() Wrappers.<CouponEntity>lambdaQuery()
.eq(CouponEntity::getId, couponId).eq(CouponEntity::getCategory, category.name())); .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); log.warn("发放优惠券失败:{},⽤户:{}", coupon, loginUser);
throw new BizException(BizCodeEnum.COUPON_NO_STOCK); throw new BizException(BizCodeEnum.COUPON_NO_STOCK);
} }
} finally { // } finally {
rLock.unlock(); // rLock.unlock();
log.info("解锁成功"); // log.info("解锁成功");
} // }
// try {
// TimeUnit.SECONDS.sleep(10L);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
return JsonData.buildSuccess(); return JsonData.buildSuccess();
} }

Loading…
Cancel
Save