SpringBoot 商城秒杀系统实现 一人一单 防止黄牛 秒杀限购 用户限制 单机模式
·
介绍
秒杀活动是吸引用户参与并增加流量的一个重要手段,由于秒杀活动的高并发和竞争激烈,如何确保秒杀活动的公平、公正和系统的稳定性。如何通过一人一单、防止黄牛和秒杀限购来构建一个高效的商城秒杀系统。
每个用户在秒杀活动中只能购买一件商品,防止某些用户通过恶意手段(如脚本)刷单。
一人一单

依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
用于 Aspect-Oriented Programming (AOP) 的实现。允许你通过切面(aspects)来增强 Java 程序的功能,比如日志、事务、权限检查等。
库存查询
@Override
@SneakyThrows
/**
* 秒杀商品
*/
public boolean secKillGood(int goodId) {
Goods goods =goodsMapper.selectById(goodId);
if(goods.getStock()<1){ //查询商品库存
return false; //没有库存
}
Integer userId=1;
//先获取锁在去完成下单的操作
synchronized (userId.toString().intern()){ //方法加锁
IGoodsService proxy =(IGoodsService) AopContext.currentProxy();
return proxy.createOrder(goodId,userId);
}
}
- userId.toString().intern():这里对 userId(假设它是一个对象)的 toString() 方法结果调用 intern() 方法,目的是将该字符串的引用指向常量池中的唯一引用。intern() 方法确保同样的字符串只有一个实例,避免创建多个相同内容的对象,从而保证锁的唯一性。
创建订单
@Override
@Transactional
/**
* 生成订单
*/
public boolean createOrder(int goodId, int userId){
//查询是否已经购买过
LambdaUpdateWrapper<Order> orderLambdaUpdateWrapper =new LambdaUpdateWrapper<>();
orderLambdaUpdateWrapper.eq(Order::getUserId,userId) //用户ID
.eq(Order::getGoodId,goodId); //商品ID
Long count =orderMapper.selectCount(orderLambdaUpdateWrapper);//查询是否已经购买过
if(count>0){ //已经购买过
return false;
}
//扣减库存
LambdaUpdateWrapper<Goods> goodsLambdaQueryWrapper =new LambdaUpdateWrapper<>();
goodsLambdaQueryWrapper.eq(Goods::getId,goodId).setSql("stock = stock-1") //扣减库存
.gt(Goods::getStock,0); //扣减时库存大于1 还有库存
//扣减库存成功 生成订单
if( goodsMapper.update(null,goodsLambdaQueryWrapper)>0){
//生成订单
Order order= new Order();
order.setGoodId(goodId);//购买的商品ID
order.setOrderId(UUID.randomUUID()+""); //生成订单编号
order.setUserId(userId);//购买的用户
return orderMapper.insert(order)>0;
}
return false;
}
暴露代理
@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
public class GoodsApplication {
public static void main(String[] args) {
SpringApplication.run(GoodsApplication.class, args);
}
}
启用 Spring AOP 的自动代理功能,允许通过 AOP 来拦截和增强方法的执行。自动配置 Spring 应用上下文中的 AOP 代理,支持基于 AspectJ 的 AOP,简化了对切面(Aspect)和增强(Advice)的配置。
一人一单

更多推荐
所有评论(0)