使用reids进行商品锁定库存帮助类

public class ComboStockRedis {


    @Autowired
    private JedisCluster jedisCluster;

    /**
     * 团购套餐数据库库存操作相关互斥锁
     */
    public static final String COMBO_STOCK_LOCK_KEY = "bsd:combo:stock:lock:key:comboId:%s";

    /**
     * 团购套餐核销数据库库存操作相关互斥锁
     */
    public static final String COMBO_VERIFY_LOCK_KEY = "bsd:combo:VERIFY:lock:key:comboCode:%s";

    /**
     * 团购套餐库存量
     */
    private static final String COMBO_STOCK_COUNT_KEY = "bsd:combo:stock:count:comboId:%s";

    /**
     * 直播团购套餐库存量
     */
    private static final String LIVE_SHOW_COMBO_STOCK_COUNT_KEY = "bsd:live:show:stock:comboId:%s";


    /**
     * 团购套餐预约数据库库存操作相关互斥锁
     */
    public static final String COMBO_APPOINT_STOCK_LOCK_KEY = "bsd:combo:appoint:stock:lock:key:comboId:%s";

    /**
     * 执行成功标识
     */
    private static final Long STOCK_SUCCESS = 1L;

    /**
     * 库存操作类型
     */
    private static final  String stockIncrType = "1";

    /**
     * 库存操作类型
     */
    private static final  String stockDecrType = "2";

    public static final long bidLockWaitTime = 5L;

    public static final long bidLockLeaseTime = 60L;


    /**
     * 库存操作脚本
     */
    public static final  String script = "if (redis.call('exists', KEYS[1]) == 1) \n" +
            "then\n" +
            "local stock = tonumber(redis.call('get', KEYS[1]));\n" +
            "local num = tonumber(ARGV[1]);\n" +
            "local type = tonumber(ARGV[2]);\n" +
            "if (type == 1) then\n" +
            "redis.call('incrby', KEYS[1], ARGV[1]);\n" +
            "return 1\n" +
            "end\n" +
            "if (type == 2) then\n" +
            "if(stock >= num) then\n" +
            "redis.call('decrby', KEYS[1], ARGV[1]);\n" +
            "return 1;\n" +
            "end\n" +
            "return -1\n" +
            "end\n" +
            "return 0\n" +
            "end\n" +
            "return -1";


    /**
     * redis库存扣减
     *
     * @param comboId
     * @param count
     * @return
     */
    public Boolean stockDecr(Integer comboId, Long count) {
        String stockKey = String.format(COMBO_STOCK_COUNT_KEY, comboId);
        List args = Lists.newArrayList();
        args.add(count.toString());
        args.add(stockDecrType);
        Object result = jedisCluster.eval(script, Collections.singletonList(stockKey), args);
        return STOCK_SUCCESS.equals(result);
    }

    public Boolean stockIncr(Integer comboId, Long count) {
        String stockKey = String.format(COMBO_STOCK_COUNT_KEY, comboId);
        List args = Lists.newArrayList();
        args.add(count.toString());
        args.add(stockIncrType);
        Object result = jedisCluster.eval(script, Collections.singletonList(stockKey), args);
        return STOCK_SUCCESS.equals(result);
    }

    public Boolean initStock(Integer comboId, Integer count){
        String stockKey = String.format(COMBO_STOCK_COUNT_KEY, comboId);
        jedisCluster.set(stockKey,count+"");
        return true;
    }

    /**
     * 判断key是否存在
     */
    public Boolean keyIsExist(String key){
        return jedisCluster.exists(key);
    }

    /**
     * 获取key的value
     */
    public String getValue(String key){
        return jedisCluster.get(key);
    }

    /**
     * 初始化直播库存,初始化成功返回true,失败返回false
     * @param showId 专场ID
     * @param comboId 套餐ID
     * @param count 初始化值
     * @return
     */
    public Boolean initShowStock(Integer showId, Integer comboId, Long count){
        String stockKey = String.format(LIVE_SHOW_COMBO_STOCK_COUNT_KEY, showId+"-"+comboId);
        String MsterStockKey = String.format(COMBO_STOCK_COUNT_KEY, comboId);
        if(keyIsExist(MsterStockKey)){
            if(count>Long.valueOf(getValue(MsterStockKey))){
                throw new BusinessException("设置的直播库存大于商品库存");
            }
        }
        jedisCluster.set(stockKey,count+"");
        return true;
    }

    /**
     * 直播库存缓存扣减
     */
    public Boolean showStockDecr(Integer showId, Integer comboId, Long count) {
        String stockKey = String.format(LIVE_SHOW_COMBO_STOCK_COUNT_KEY, showId+"-"+comboId);
        List args = Lists.newArrayList();
        args.add(count.toString());
        args.add(stockDecrType);
        Object result = jedisCluster.eval(script, Collections.singletonList(stockKey), args);
        return STOCK_SUCCESS.equals(result);
    }

    /**
     * 直播库存增加
     */
    public Boolean showStockIncr(Integer showId, Integer comboId, Long count) {
        String stockKey = String.format(LIVE_SHOW_COMBO_STOCK_COUNT_KEY, showId+"-"+comboId);
        List args = Lists.newArrayList();
        args.add(count.toString());
        args.add(stockIncrType);
        Object result = jedisCluster.eval(script, Collections.singletonList(stockKey), args);
        return STOCK_SUCCESS.equals(result);
    }

    /**
     * 返还直播库存
     * @param showId 专场ID
     * @param comboId 套餐ID
     * @return
     */
    public Boolean returnShowStock(Integer showId, Integer comboId){
        String stockKey = String.format(LIVE_SHOW_COMBO_STOCK_COUNT_KEY, showId+"-"+comboId);
        if(keyIsExist(stockKey)){
            stockIncr(comboId,Long.valueOf(getValue(stockKey)));
            jedisCluster.del(stockKey);
            return true;
        }
        return false;
    }

你可能感兴趣的:(redis)