秒杀使用redis分布式锁

使用的是springboot -data-redis

这个service

@Service
public class SecKillServiceImpl implements SekillService {
      private static final int TIMEOUT =10* 1000;

    @Autowired
    private RedisLock redisLock;

    static Map<String,Integer> products;
    static  Map<String,String> orders;
    static  Map<String,Integer> stock;
   static
   {
       products=new HashMap<>();
       orders=new HashMap<>();
       stock=new HashMap<>();
       products.put("123456",100000);
       stock.put("123456",100000);
   }

   private String queryMap(String productId){
       return  "国庆 活动,皮蛋粥特价,限量粉"+products.get(productId)
               +"还剩: "+stock.get(productId) + " 份"
               + "该商品成功下单的数目: "
               +orders.size() +" 人";

   }
    @Override
    public String querySeckillProductInfo(String productId) {
        return this.queryMap(productId);
    }

    @Override
    public void orderProductMockDiffUser(String productId) {
       //加锁
        long time=System.currentTimeMillis()+TIMEOUT;
        if (! redisLock.lock(productId, String.valueOf(time))){
           throw new SellException(101,"人也太多了,换个姿势试试") ;
        }


        int stockNum=stock.get(productId);
       if (stockNum==0){
           throw  new SellException(100,"活动结束");
       }else{
           orders.put(KeyUtil.genUniqueKey(),productId);
           stockNum=stockNum-1;

           try{
               Thread.sleep(100);
           } catch ( InterruptedException e){
               e.printStackTrace();
           }
            stock.put(productId,stockNum);
       }



       //解锁
     redisLock.unlock(productId,String.valueOf(time));


    }

 这个是锁

@Component
public class RedisLock {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     *加锁
     * @param key  productid作为key
     * @param value 当前时间+超时时间
     * @return
     */
    public  boolean lock(String key,String value){
        if(stringRedisTemplate.opsForValue().setIfAbsent(key,value)){
            return  true;
        }
        //判断锁是否超时

        String currentValue = stringRedisTemplate.opsForValue().get(key);
        //如果锁过期
        if (!StringUtils.isEmpty(currentValue)&&Long.parseLong(currentValue)<System.currentTimeMillis()){
        // 获取上一个锁的时间
            String oldValue = stringRedisTemplate.opsForValue().getAndSet(key, value);
            if (!StringUtils.isEmpty(oldValue)&&oldValue.equals(currentValue)){
                return  true;
            }
        }
        return  false;
    }

    /***
     * 解锁
     * @param key
     * @param value
     */
    public  void  unlock(String key,String value){
        try {
            String currentValue = stringRedisTemplate.opsForValue().get(key);

            if (!StringUtils.isEmpty(currentValue)&&currentValue.equals(value)){
                stringRedisTemplate.opsForValue().getOperations().delete(key);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_42047790/article/details/82630471