private static final Long SUCCESS = 1L;
private static String script1 = "if redis.call('setNx',KEYS[1],ARGV[1]) then " +
" if redis.call('get',KEYS[1])==ARGV[1] then " +
" return redis.call('expire',KEYS[1],ARGV[2]) " +
" else " +
" return 0 " +
" end " +
"end";
private RedisScript<String> lockRedisScript1 = new DefaultRedisScript<>(script1, String.class);
private static String script2 = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
private RedisScript<String> unLockRedisScript = new DefaultRedisScript<>(script2, String.class);
/**
* 獲取鎖
*
* @param lockKey redis的key
* @param value redis的value要求是隨機串,防止釋放其他請求的鎖
* @param expireTime redis的key 的過期時間 單位(秒) 防止死鎖,導致其他請求無法正常執行業務
* @return
*/
@Override
public boolean lock(String lockKey, String value, long expireTime) {
//對非string類型的序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
Object result = redisTemplate.execute(lockRedisScript1, Collections.singletonList(lockKey), value, String.valueOf(expireTime));
return SUCCESS.equals(result);
}
/**
* 釋放鎖
*
* @param lockKey redis的key
* @param value redis的value 只有value比對一致,才能確定是本請求 加的鎖 才能正常釋放
* @return
*/
@Override
public boolean unlock(String lockKey, String value) {
try {
Object result = redisTemplate.execute(unLockRedisScript, Collections.singletonList(lockKey), value);
if (SUCCESS.equals(result)) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}