首页 > 技术文章 > Redis分布式锁

wzdnwyyu 2019-07-10 14:19 原文

实现分布式锁的几种方式
  1. 数据库锁:性能不好,效率低。
  2. Redis分布式锁(setnx):setnx存入key如果存入成功返回1,如果key已经存在返回0,只要谁创建key成功,谁就能获取到锁。redis执行完操作的时候删除key释放锁,如果删除失败,就释放锁失败了。所以最好的办法是给key设置有效期,避免死锁。
 
redis分布式锁的核心方法
  1. 获取锁(参数:1.获取锁之前的超时时间2.获取锁之后的超时时间)
    1. 获取锁的步骤可以总结为:
      1. 建立redis
      2. 生成value
      3. 定义锁名称
      4. 定义过期时间
      5. 定义在获取锁之前,获取的超时时间
      6. 使用setnx设置锁值
  2. 释放锁
    1. 释放锁的两种方式:
      1. key自动过期
      2. public String lockWithTimeout(String lockKey, Long acquireTimeout, Long timeOut) {
        		Jedis conn = null;
        		String retIdentifierValue = null;
        		try {
        			// 1.建立redis连接
        			conn = jedisPool.getResource();
        			// 2.随机生成一个value
        			String identifierValue = UUID.randomUUID().toString();
        			// 3.定义锁的名称
        			String lockName = "redis_lock" + lockKey;
        			// 4.定义上锁成功之后,锁的超时时间
        			int expireLock = (int) (timeOut / 1000);
        			// 5.定义在没有获取锁之前,锁的超时时间
        			Long endTime = System.currentTimeMillis() + acquireTimeout;
        			while (System.currentTimeMillis() < endTime) {
        				// 6.使用setnx方法设置锁值
        				if (conn.setnx(lockName, identifierValue) == 1) {
        					// 7.判断返回结果如果为1,则可以成功获取锁,并且设置锁的超时时间
        					conn.expire(lockName, expireLock);
        					retIdentifierValue = identifierValue;
        					return retIdentifierValue;
        				}
        				// 8.否则情况下继续循环等待
        			}
        
        		} catch (Exception e) {
        			e.printStackTrace();
        		} finally {
        			if (conn != null) {
        				conn.close();
        			}
        		}
        		return retIdentifierValue;
        	}
        

          

        会遇到的两个超时问题
        1. 在规定时间内还没有获取锁,直接放弃。
        2. 获取锁成功后,对应的key的有效期,对应的key,在规定的时间内失效。
         
        时间戳和uuid在redis分布式锁中最好不要用吧。

推荐阅读