Redis实现分布式锁

作者:Redis实现分布式锁 来源:未知 2022-06-21 09:11   阅读:

publicclassRedisBillLockHandlerimplementsIBatchBillLockHandler{privatestaticfinalLoggerLOGGER=Logger


public class RedisBillLockHandler implements IBatchBillLockHandler {

private static final Logger LOGGER=LoggerFactory.getLogger(RedisBillLockHandler.class);

private static final int DEFAULT_SINGLE_EXPIRE_TIME=3;

private static final int DEFAULT_BATCH_EXPIRE_TIME=6;

private final JedisPool jedisPool;


public RedisBillLockHandler(JedisPool jedisPool) {
this.jedisPool=jedisPool;
}


public boolean tryLock(IBillIdentify billIdentify) {
return tryLock(billIdentify, 0L, null);
}


public boolean tryLock(IBillIdentify billIdentify, long timeout, TimeUnit unit) {
String key=(String) billIdentify.uniqueIdentify();
Jedis jedis=null;
try {
jedis=getResource();
long nano=System.nanoTime();
do {
LOGGER.debug("try lock key: " + key);
Long i=jedis.setnx(key, key);
if (i==1) {
jedis.expire(key, DEFAULT_SINGLE_EXPIRE_TIME);
LOGGER.debug("get lock, key: " + key + " , expire in " + DEFAULT_SINGLE_EXPIRE_TIME + " seconds.");
return Boolean.TRUE;
} else { // 存在锁
if (LOGGER.isDebugEnabled()) {
String desc=jedis.get(key);
LOGGER.debug("key: " + key + " locked by another business:" + desc);
}
}
if (timeout==0) {
break;
}
Thread.sleep(300);
} while ((System.nanoTime() - nano) < unit.toNanos(timeout));
return Boolean.FALSE;
} catch (JedisConnectionException je) {
LOGGER.error(je.getMessage(), je);
returnBrokenResource(jedis);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
} finally {
returnResource(jedis);
}
return Boolean.FALSE;
}


public void lock(IBillIdentify billIdentify) {
String key=(String) billIdentify.uniqueIdentify();
Jedis jedis=null;
try {
jedis=getResource();
do {
LOGGER.debug("lock key: " + key);
Long i=jedis.setnx(key, key);
if (i==1) {
jedis.expire(key, DEFAULT_SINGLE_EXPIRE_TIME);
LOGGER.debug("get lock, key: " + key + " , expire in " + DEFAULT_SINGLE_EXPIRE_TIME + " seconds.");
return;
} else {
if (LOGGER.isDebugEnabled()) {
String desc=jedis.get(key);
LOGGER.debug("key: " + key + " locked by another business:" + desc);
}
}
Thread.sleep(300);
} while (true);
} catch (JedisConnectionException je) {
LOGGER.error(je.getMessage(), je);
returnBrokenResource(jedis);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
} finally {
returnResource(jedis);
}
}


public void unLock(IBillIdentify billIdentify) {
List list=new ArrayList();
list.add(billIdentify);
unLock(list);
}


public boolean tryLock(List billIdentifyList) {
return tryLock(billIdentifyList, 0L, null);
}


public boolean tryLock(List billIdentifyList, long timeout, TimeUnit unit) {
Jedis jedis=null;
try {
List needLocking=new CopyOnWriteArrayList();
List locked=new CopyOnWriteArrayList();
jedis=getResource();
long nano=System.nanoTime();
do {
// 构建pipeline,批量提交
Pipeline pipeline=jedis.pipelined();
for (IBillIdentify identify : billIdentifyList) {
String key=(String) identify.uniqueIdentify();
needLocking.add(key);
pipeline.setnx(key, key);
}
LOGGER.debug("try lock keys: " + needLocking);
// 提交redis执行计数
List results=pipeline.syncAndReturnAll();
for (int i=0; i < results.size(); ++i) {
Long result=(Long) results.get(i);
String key=needLocking.get(i);
if (result==1) { // setnx成功,获得锁
jedis.expire(key, DEFAULT_BATCH_EXPIRE_TIME);
locked.add(key);
}
}
needLocking.removeAll(locked); // 已锁定资源去除

if (CollectionUtils.isEmpty(needLocking)) {
return true;
} else {
// 部分资源未能锁住
LOGGER.debug("keys: " + needLocking + " locked by another business:");
}

if (timeout==0) {
break;
}
Thread.sleep(500);
} while ((System.nanoTime() - nano) < unit.toNanos(timeout));

// 得不到锁,释放锁定的部分对象,并返回失败
if (!CollectionUtils.isEmpty(locked)) {
jedis.del(locked.toArray(new String[0]));
}
return false;
} catch (JedisConnectionException je) {
LOGGER.error(je.getMessage(), je);
returnBrokenResource(jedis);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
} finally {
returnResource(jedis);
}
return true;
}


public void unLock(List billIdentifyList) {
List keys=new CopyOnWriteArrayList();
for (IBillIdentify identify : billIdentifyList) {
String key=(String) identify.uniqueIdentify();
keys.add(key);
}
Jedis jedis=null;
try {
jedis=getResource();
jedis.del(keys.toArray(new String[0]));
LOGGER.debug("release lock, keys :" + keys);
} catch (JedisConnectionException je) {
LOGGER.error(je.getMessage(), je);
returnBrokenResource(jedis);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
} finally {
returnResource(jedis);
}
}


private Jedis getResource() {
return jedisPool.getResource();
}


private void returnBrokenResource(Jedis jedis) {
if (jedis==null) {
return;
}
try {
//容错
jedisPool.returnBrokenResource(jedis);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}


private void returnResource(Jedis jedis) {
if (jedis==null) {
return;
}
try {
jedisPool.returnResource(jedis);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}

分享给小伙伴们:
Redis实现分布式锁:如果本文侵犯了您的权利, 请联系本网立即做出处理,谢谢。
当前位置:殿试作文网 > 日语作文大海Redis实现分布式锁转载请注明出处。
下一篇:没有了
Redis实现分布式锁相关文章