淘东电商项目(75) -秒杀系统(用户操作频率限制)

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: 淘东电商项目(75) -秒杀系统(用户操作频率限制)

引言

本文代码已提交至Github(版本号:a08c2b261d8cd31850ccebc38a4a6620090e619f),有兴趣的同学可以下载来看看:https://github.com/ylw-github/taodong-shop

在上一篇博客《淘东电商项目(74) -秒杀系统(库存超卖解决方案)主要讲解了库存超卖的解决,继续完善上一篇博客的代码,以下的第二个步骤:

@Transactional
public BaseResponse<JSONObject> spike(String phone, Long seckillId) {
  // 1.参数验证
  if (StringUtils.isEmpty(phone)) {
    return setResultError("手机号码不能为空!");
  }
  if (seckillId == null) {
    return setResultError("商品库存id不能为空!");
  }
  SeckillEntity seckillEntity = seckillMapper.findBySeckillId(seckillId);
  if (seckillEntity == null) {
    return setResultError("商品信息不存在!");
  }
  // 2.用户频率限制 setnx 如果key存在话
  // 3.(悲观锁 )修改数据库对应的库存 1万中只有100个抢购成功 提前生成好100个token 谁能够抢购成功token放入到mq中实现异步修改库存
  int inventoryDeduction = seckillMapper.pessimisticDeduction(seckillId);
  if (!toDaoResult(inventoryDeduction)) {
    log.info(">>>修改库存失败>>>>inventoryDeduction返回为{} 秒杀失败!", inventoryDeduction);
    return setResultError("亲,请稍后重试!");
  }
  // 4.添加秒杀成功订单 基于MQ实现异步形式
  OrderEntity orderEntity = new OrderEntity();
  orderEntity.setUserPhone(phone);
  orderEntity.setSeckillId(seckillId);
  int insertOrder = orderMapper.insertOrder(orderEntity);
  if (!toDaoResult(insertOrder)) {
    return setResultError("亲,请稍后重试!");
  }
  log.info(">>>修改库存成功>>>>inventoryDeduction返回为{} 秒杀成功", inventoryDeduction);
  return setResultSuccess("恭喜您,秒杀成功!");
}

本文目录结构:

l____引言

l____ 1.用户操作频率限制代码实现

l____ 2. 测试

1.用户操作频率限制代码实现

用户的操作频率限制很简单,可以使用Redis的操作机制限制,Redis超时设置通用方法如下:

/**
 * description: 如果key存在的话返回fasle 不存在的话返回true
 * create by: YangLinWei
 * create time: 2020/5/25 5:45 下午
 */
public Boolean setNx(String key, String value, Long timeout) {
  Boolean setIfAbsent = stringRedisTemplate.opsForValue().setIfAbsent(key, value);
  if (timeout != null) {
    stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);
  }
  return setIfAbsent;
}

完善第二步骤:

@Transactional
public BaseResponse<JSONObject> spike(String phone, Long seckillId) {
  // 1.参数验证
  if (StringUtils.isEmpty(phone)) {
    return setResultError("手机号码不能为空!");
  }
  if (seckillId == null) {
    return setResultError("商品库存id不能为空!");
  }
  SeckillEntity seckillEntity = seckillMapper.findBySeckillId(seckillId);
  if (seckillEntity == null) {
    return setResultError("商品信息不存在!");
  }
  // 2.用户频率限制 setnx 如果key存在话
  Boolean reusltNx = redisUtil.setNx(phone, seckillId + "", 10l);
  if (!reusltNx) {
    return setResultError("访问次数过多,10秒后在实现重试!");
  }
  // 3.(悲观锁 )修改数据库对应的库存 1万中只有100个抢购成功 提前生成好100个token 谁能够抢购成功token放入到mq中实现异步修改库存
  int inventoryDeduction = seckillMapper.pessimisticDeduction(seckillId);
  if (!toDaoResult(inventoryDeduction)) {
    log.info(">>>修改库存失败>>>>inventoryDeduction返回为{} 秒杀失败!", inventoryDeduction);
    return setResultError("亲,请稍后重试!");
  }
  // 4.添加秒杀成功订单 基于MQ实现异步形式
  OrderEntity orderEntity = new OrderEntity();
  orderEntity.setUserPhone(phone);
  orderEntity.setSeckillId(seckillId);
  int insertOrder = orderMapper.insertOrder(orderEntity);
  if (!toDaoResult(insertOrder)) {
    return setResultError("亲,请稍后重试!");
  }
  log.info(">>>修改库存成功>>>>inventoryDeduction返回为{} 秒杀成功", inventoryDeduction);
  return setResultSuccess("恭喜您,秒杀成功!");
}

2. 测试

浏览器访问:http://localhost:9800/spike?phone=13800000001&seckillId=100001

浏览器立刻再次访问:

可以看到通过redis可以控制用户访问的频率,本文完!

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
数据挖掘 黑灰产治理
排队免单商城系统开发详细案例/方案项目/源码指南
排队免单商城系统开发设计是指开发一种商城系统,其中用户可以通过排队活动获得商品免单的机会。
|
7月前
|
缓存 前端开发 安全
淘东电商项目(73) -秒杀系统(前端优化)
淘东电商项目(73) -秒杀系统(前端优化)
87 0
|
1月前
|
新零售 人工智能 供应链
排队免单返利商城系统开发|成熟源码部署|案例详情
新零售业是零售业发展的重要趋势,它通过技术的创新和变革,重新定义了传统零售业的模式和方式
|
1月前
|
新零售 供应链 数据挖掘
排队返利新零售身材系统开发|模式案例|详情
商业模式则是随着这些概念成熟运用与整合产生,并且最终形成一个将市场需求与资源整合起来的商业式系统。
|
7月前
|
SQL 前端开发 Java
淘东电商项目(74) -秒杀系统(库存超卖解决方案)
淘东电商项目(74) -秒杀系统(库存超卖解决方案)
94 0
|
7月前
|
设计模式 算法 安全
淘东电商项目(78) -秒杀系统(服务保护)
淘东电商项目(78) -秒杀系统(服务保护)
51 0
|
7月前
|
前端开发 NoSQL 算法
淘东电商项目(77) -秒杀系统(小结)
淘东电商项目(77) -秒杀系统(小结)
33 0
|
7月前
|
SQL
淘东电商项目(55) -支付系统核心表设计
淘东电商项目(55) -支付系统核心表设计
90 0
|
7月前
|
消息中间件 NoSQL 前端开发
淘东电商项目(76) -秒杀系统(完整代码实现)
淘东电商项目(76) -秒杀系统(完整代码实现)
64 0
|
8月前
|
前端开发 JavaScript API
89分布式电商项目 -检测支付状态
89分布式电商项目 -检测支付状态
25 0