DistributedLock
程序员文章站
2022-04-19 08:22:28
...
private volatile String unlockSha1 = "";
public String lock(String lockName, long acquireTime, int lockTimeout) {
String identifier = UuidUtil.generate32Value();
String lock = "lock:" + lockName;
long beginTime = System.currentTimeMillis();
do {
String result = jedisCluster.set(lock, identifier, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, lockTimeout);
if (LOCK_SUCCESS.equalsIgnoreCase(result)) {
return identifier;
}
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
log.error("acquireDistributedLock error:",e);
}
} while (System.currentTimeMillis() - beginTime < acquireTime);
return null;
}
//identifier 为lock返回值
public boolean releaseDistributedLock(String lockName, String identifier) {
String lock = "lock:" + lockName;
List<String> keys = Collections.singletonList(lock);
List<String> args = Collections.singletonList(identifier);
try {
Object result = jedisCluster.evalsha(unlockSha1, keys, args);
return RELEASE_SUCCESS.equals(result);
} catch (JedisNoScriptException e) {
//没有脚本缓存时,重新发送缓存
log.info("try to store script......");
storeScript(lock);
Object result = jedisCluster.evalsha(unlockSha1, keys, args);
return RELEASE_SUCCESS.equals(result);
} catch (Exception e){
log.error("releaseDistributedLock error:",e);
return false;
}
}
private void storeScript(String lock){
if (StringUtil.isEmpty(unlockSha1) || !jedisCluster.scriptExists(unlockSha1, lock)){
//redis支持脚本缓存,返回哈希码,后续可以继续用来调用脚本
unlockSha1 = jedisCluster.scriptLoad(DEL_SCRIPT, lock);
}
}
public String lock(String lockName, long acquireTime, int lockTimeout) {
String identifier = UuidUtil.generate32Value();
String lock = "lock:" + lockName;
long beginTime = System.currentTimeMillis();
do {
String result = jedisCluster.set(lock, identifier, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, lockTimeout);
if (LOCK_SUCCESS.equalsIgnoreCase(result)) {
return identifier;
}
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
log.error("acquireDistributedLock error:",e);
}
} while (System.currentTimeMillis() - beginTime < acquireTime);
return null;
}
//identifier 为lock返回值
public boolean releaseDistributedLock(String lockName, String identifier) {
String lock = "lock:" + lockName;
List<String> keys = Collections.singletonList(lock);
List<String> args = Collections.singletonList(identifier);
try {
Object result = jedisCluster.evalsha(unlockSha1, keys, args);
return RELEASE_SUCCESS.equals(result);
} catch (JedisNoScriptException e) {
//没有脚本缓存时,重新发送缓存
log.info("try to store script......");
storeScript(lock);
Object result = jedisCluster.evalsha(unlockSha1, keys, args);
return RELEASE_SUCCESS.equals(result);
} catch (Exception e){
log.error("releaseDistributedLock error:",e);
return false;
}
}
private void storeScript(String lock){
if (StringUtil.isEmpty(unlockSha1) || !jedisCluster.scriptExists(unlockSha1, lock)){
//redis支持脚本缓存,返回哈希码,后续可以继续用来调用脚本
unlockSha1 = jedisCluster.scriptLoad(DEL_SCRIPT, lock);
}
}