On redis Distributed Lock Usage

Redis use of setnx command to achieve

@Component
@Slf4j
public class RedisLock {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 加锁
     *
     * @param 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) {
            log.error("【redis分布式锁】 解锁异常,{}", e);
        }

    }
}

demo

@Service
public class SecKillServiceImpl implements SeckillService {
    //超时时间10秒
    private static final int       TIMEOUT = 10 * 1000;
    @Autowired
    private              RedisLock redisLock;

    static Map<String, Integer> products;
    static Map<String, Integer> stock;
    static Map<String, String>  orders;

    {
        products = new HashMap<>();
        stock = new HashMap<>();
        Orders = new new the HashMap <> (); 
        products.put ( "123456", 100000 ); 
        stock.put ( "123456", 100000 ); 
    } 

    Private String QueryMap (String the productId) {
         return "celebrations, egg soup cheap, Limited parts " 
                + products.get (the productId)
                 +" left: "+ stock.get (productId) + " parts " 
                +" under the item number of successful single-user: " 
                + orders.size () +" person " ;
    }

    @Override
    public  void orderProductMockDiffUser(String productId) {
        Long time = System.currentTimeMillis() +TIMEOUT;
         // lock 
        IF (! RedisLock.lock (productId, String.valueOf (Time))) {
             the throw  new new SellException (101, "whoops Hey, too many people in try" ); 
        } 

        Integer stockNum = stock.get (the productId);
         IF (stockNum == 0 ) {
             the throw  new new SellException (100, "end of the event" ); 
        } the else {
             // single 
            orders.put (KeyUtil.genUniqueKey (), the productId);
             // Stock Save 
            stockNum stockNum = -. 1 ;
             the try {
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
            stock.put(productId, stockNum);
        }
        //解锁
        redisLock.unlock(productId, String.valueOf(time));
    }

    @Override
    public String querySecKillProductInfo(String productId) {
        return queryMap(productId);
    }
}

 

Guess you like

Origin www.cnblogs.com/panbingqi/p/11281573.html