自定义分布式锁
public boolean tryLock(String lockKey, String requestId, int expireTime,long waitTimeout) {
lockKey = wrapperPrefix(lockKey);
long nanoTime = System.nanoTime();
try{
String script = "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";
logger.info("开始获取分布式锁-key[{}]",lockKey);
int count = 0;
do{
RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
logger.debug("尝试获取分布式锁-key[{}]requestId[{}]count[{}]",lockKey,requestId,count);
Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey),requestId,expireTime);
if(SUCCESS.equals(result)) {
logger.debug("尝试获取分布式锁-key[{}]成功",lockKey);
return true;
}
Thread.sleep(500L);
count++;
}while ((System.nanoTime() - nanoTime) < TimeUnit.MILLISECONDS.toNanos(waitTimeout));
}catch(Exception e){
logger.error("尝试获取分布式锁-key["+lockKey+"]异常",e);
}
logger.warn("获取分布式锁-key[{}]失败",lockKey);
return false;
}
public boolean releaseLock(String lockKey, String requestId) {
lockKey = wrapperPrefix(lockKey);
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), requestId);
if (SUCCESS.equals(result)) {
logger.info("释放分布式锁-key[{}]成功",lockKey);
return true;
}
logger.error("释放分布式锁-key[{}]失败",lockKey);
return false;
}
private String wrapperPrefix(String key){
return PREFIX + key;
}