利用redis的原子性实现最简单的秒杀不超卖

574 阅读1分钟

前言:最近在学习琢磨redis在分布式锁的应用,网上看了很多资料,在类似于秒杀的解决方案中,几乎无一例外的用到了分布式锁,而且若是使用不当,还会造成A线程释放掉B线程的问题。然后我就试了下利用redis的原子命令,发现也不会超卖......就纳闷为什么这种场景下为什么非要用分布式锁呢?我把测试结果贴出来,希望有大佬能一起讨论。

直接上结果吧

代码:

        //1.获取redis中的库存数量        String count = redisTemplate.opsForValue().get(Init.GOODS_KEY);        if (Integer.parseInt(count) <= 0) {            log.info("秒杀结束");            return;        }        //设置锁//        String lockKey = "key";//        RLock lock = redisson.getLock(lockKey);//        try {        //加锁//            lock.lock();        //秒杀开始,基于原子性扣减库存        Long stockCount = redisTemplate.boundValueOps(Init.GOODS_KEY).decrement(1);        if (stockCount <= 0) {            log.info("库存不足,扣减失败");            return;        }        log.info("扣减成功,剩余库存:" + stockCount);        //生成订单,执行业务逻辑

用jmeter测试2000个线程的并发:

结果:正常,并无出现超卖问题,就是会出现先到的线程返回的是没有库存的结果,后来的反而可以秒杀成功。如果用redission锁的话就不会。