淘东电商项目(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可以控制用户访问的频率,本文完!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值