Redis锁

一、Redis加锁流程

加锁步骤:

​ 1、判断Redis锁是否存在;

​ 2、若不存在则加锁,并给锁加上有效期,防止死锁;

正确做法:

public Boolean Lock(String key, String val, long milliSeconds) {
        return redisTemplate.execute((RedisCallback) redisConnection -> {
            Jedis jedis = (Jedis) redisConnection.getNativeConnection();
            String result = jedis.set(key, val, "NX", "PX", milliSeconds);
            if (LOCK_SUCCESS.equals(result)) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        });
    }
    1、第一个参数是key,
    2、第二个参数是requestId,确定是哪一个请求加的锁,
    3、第三个参数的NX表示 不存在则添加,
    4、第四个参数的PX表示 时间单位为毫秒,
    5、第五个参数表示有效期时间

错误操作:

public static void wrongGetLock1(Jedis jedis, String lockKey, String requestId, int expireTime) {

    Long result = jedis.setnx(lockKey, requestId);
    if (result == 1) {
        // 若在这里程序突然崩溃,则无法设置过期时间,将发生死锁
        jedis.expire(lockKey, expireTime);
    }

}

二、Redis解锁流程

解锁流程:

​ 1、判断锁是否存在;

​ 2、判断value是否和requestId相等;

​ 3、删除锁;

正确做法:

private static final Long RELEASE_SUCCESS = 1L;

private static final String RELEASE_LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";

public Boolean releaseLock(String key, String val) {
        return redisTemplate.execute((RedisCallback) redisConnection -> {
            Jedis jedis = (Jedis) redisConnection.getNativeConnection();
            Object result = jedis.eval(RELEASE_LOCK_SCRIPT, Collections.singletonList(key),
                    Collections.singletonList(val));
            if (RELEASE_SUCCESS.equals(result)) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        });
    }

错误操作:

public static void wrongReleaseLock(Jedis jedis, String lockKey, String requestId) {
        
    // 判断加锁与解锁是不是同一个客户端
    if (requestId.equals(jedis.get(lockKey))) {
        // 若在此时,这把锁突然不是这个客户端的,则会误解锁
        jedis.del(lockKey);
    }

}

Redis客户端链接

https://github.com/Sidfate/RedisCX/releases/download/v0.5.4/RedisCX.Setup.0.5.4.exe

你可能感兴趣的:(Redis锁)