一、 防止恶意刷单解决
在生产场景下,可能会有一些人会恶意访问当前网站,来进行恶意的刷单。这样会造成当前系统出现一些业务上的业务混乱,出现脏数据,或者造成后端访问压力大等问题。
一般要解决这个问题的话,前端可以进行控制,如点一次立即抢购后,置灰立即抢购按钮。同时对于后端来说也需要进行控制。后端实现可以通过Redis incrde 原子性递增来进行解决。
实现思路:
获取登录人名称和商品ID,自定义RedisKey,用户第一次访问放行,并对当前Key设置一个5分钟的有效期,用户在 5分钟内不能重复访问。
步骤一: 更新秒杀服务下单方法
更新秒杀服务下单方法,防止恶意刷单。
步骤二: 防重方法实现
//防止重复提交
private String preventRepeatCommit(String username,Long id) {
String redisKey = "seckill_user_" + username+"_id_"+id;long count = redisTemplate.opsForValue().increment(redisKey, 1);if (count == 1){//设置有效期五分钟redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES);return "success";}
if (count>1){return "fail";}
return "fail";
}
二、 防止相同商品重复秒杀
防止同一个人,对于相同商品的重复秒杀。项目的需求是:同一个人对于相同的商品只能买一次。并且每次只能买一个。
实现思路:
当用户购买完商品之后,会在秒杀订单表中产生一条记录,这条记录里包含当前购买的商品ID,以及当前的用户名称。现在明确了每一个
订单中都有这两个信息的话,我们需要完成防止同一个人对于同一个商品的重复秒杀。只需要根据秒杀ID和秒杀商品ID来查询秒杀订单表
,如果里面有相关数据的话,代表用户下过单,就不让用户下单了,如果没有的话再来完成下单流程。
步骤一: 修改下单业务层实现
判断用户是否已经购买过该商品。
步骤二: dao层新增查询方法
public interface SeckillOrderMapper extends Mapper<SeckillOrder> {
/*** 查询秒杀订单信息* @param username* @param id* @return*/@Select("select * from tb_seckill_order where user_id=#{username} and seckill_id=#{id}")SeckillOrder getSecKillOrderByUserNameAndGoodsId(String username, Long id);
}