使用redis解决超卖问题

高并发下超卖问题及如何解决

主要思路是:
1. 首先在团购秒杀开始前将需要的物品库存信息放入缓存中
2. 使用锁来处理其并发请求
3. 将缓存中的数据同步到数据库。

我们此处使用redis作为缓存。
应用操作redis减库存的大体思路为:
1. 首先通过redis api监听相关物品的库存信息,在事务开启前保证该物品库存信息无人修改
2. 获取现有库存信息,判断库存不为0并且当前库存量大于等于订单所需数量
3. 满足上述2的话则进行扣除操作
4. 如果在1的过程中有别人更新了该物品库存信息版本,则重试
5. 直到库存为0或者剩余库存不满足当前订单扣除数量退出

具体代码如下:
 public void secondBuyProduct(Jedis jedis, String stockId, int orders) {
    
    
        //CAS重试
        while (true) {
    
    
            try {
    
    
                //监视key,如果在后续事务执行之前key的值被其他命令所改动,那么事务将被打断
                jedis.watch(stockId);

                int prdNum = Integer.parseInt(jedis.get(stockId));
                //判断库存是否满足订单数量要求
                if (prdNum > 0 && prdNum - orders >= 0)) {
    
    

                    Transaction transaction = jedis.multi();
                    //减库存并写入
                    transaction.set(stockId, String.valueOf(prdNum - orders));

                    List<Object> res = transaction.exec();
                    //事务提交后如果为null,说明key值在本次事务提交前已经被改变,本次事务不执行。
                    if (res != null && !res.isEmpty()) {
    
    
                        System.out.println("抢购成功!");
                        break;
                    }

                } else {
    
    
                    System.err.println("被抢光了!");
                    break;
                }
            } catch (Exception e) {
    
    
                System.err.println("抢购出错:" + e.toString());
                e.printStackTrace();
            } finally {
    
    
                jedis.unwatch();
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_43871678/article/details/114319892