zoukankan      html  css  js  c++  java
  • Redis分布式锁解决抢购问题

    转:https://segmentfault.com/a/1190000011421467

    废话不多说,首先分享一个业务场景-抢购。一个典型的高并发问题,所需的最关键字段就是库存,在高并发的情况下每次都去数据库查询显然是不合适的,因此把库存信息存入Redis中,利用redis的锁机制来控制并发访问,是一个不错的解决方案。

    首先是一段业务代码:

    @Transactional
    public void orderProductMockDiffUser(String productId){
        //1.查库存
        int stockNum  = stock.get(productId);
        if(stocknum == 0){
            throw new SellException(ProductStatusEnum.STOCK_EMPTY);
            //这里抛出的异常要是运行时异常,否则无法进行数据回滚,这也是spring中比较基础的   
        }else{
            //2.下单
            orders.put(KeyUtil.genUniqueKey(),productId);//生成随机用户id模拟高并发
            sotckNum = stockNum-1;
            try{
                Thread.sleep(100);
            } catch (InterruptedExcption e){
                e.printStackTrace();
            }
            stock.put(productId,stockNum);
        }
    }

    这里有一种比较简单的解决方案,就是synchronized关键字。

    public synchronized void orderProductMockDiffUser(String productId)

    这就是java自带的一种锁机制,简单的对函数加锁和释放锁。但问题是这个实在是太慢了,感兴趣的可以可以写个接口用apache ab压测一下。

    ab -n 500 -c 100 http://localhost:8080/xxxxxxx

    下面就是redis分布式锁的解决方法。首先要了解两个redis指令
    SETNX 和 GETSET,可以在redis中文网上找到详细的介绍。
    SETNX就是set if not exist的缩写,如果不存在就返回保存value并返回1,如果存在就返回0。
    GETSET其实就是两个指令GET和SET,首先会GET到当前key的值并返回,然后在设置当前Key为要设置Value。

    首先我们先新建一个RedisLock类:

  • 相关阅读:
    数组的地址和vector数组的地址
    字节跳动 测试开发工程师 面经
    最短路径树
    SPFA
    树的直径
    树的重心
    CF1401D Maximum Distributed Tree
    期望简述
    CF723E One-Way Reform
    CF1409E Two Platforms
  • 原文地址:https://www.cnblogs.com/duende99/p/11553745.html
Copyright © 2011-2022 走看看