用redis实现分布式锁

通常部署的服务都是在多台服务器上,不会只有一台。那么在分布式环境下,就会遇到共享资源的问题。比如一个人只能有一条记录,下次进来就只能修改,而不是再新增。
如果只有一台服务器,可以使用多线程下的单例模式来控制,但是分布式下,就不管用了。

有三种方式,一是使用数据库的乐观锁,二是redis的锁,三是zookeeper提供的锁。此处介绍reids的,参考这个网址:https://www.cnblogs.com/linjiqin/p/8003838.html

以下为参考他人博客整理后的代码。

以下为调用代码

String lockKey=“xxxxkey”;
String requestId=UUID.randomUUID().toString();
String lockResult=RedisUtil.lockWithSecond(lockKey,requestId,30);
if(!RedisConstants.LOCK_SUCCESS.equals(lockResult)){
    获得锁失败处理逻辑,可以是暂停等待之类的操作。。。
}

try{
。。。。获得锁成功业务逻辑
}catch(Exceptionee){
}finally{
  解锁
RedisUtil.unLock(lockKey,requestId);
}

redis工具类的加锁代码

/**
 *  锁的超时单位为秒
 *  @param lockKey,锁的key(名称)
 * @param requestId,加锁的客户端id
 * @param expireTime 失效时间
 *  返回 OK 表示成功
 */
public static String lockWithSecond(String lockKey,String requestId,int expireTime){
   String result=myRedisClusterForHessian.getJedisCluster().set(
            lockKey,
            requestId,
            "NX",
            "EX",
           expireTime);
   return result;
}

redis工具类的解锁代码

/**
 * 解锁,0-失败,1-成功
 * @return
 */
public static Long unLock(String lockKey,String requestId){
    if (requestId.equals(myRedisClusterForHessian.getJedisCluster().get(lockKey))) {
        return myRedisClusterForHessian.getJedisCluster().del(lockKey);
    }else{
        return 0L;
    }
}

其实就是用了jedis提供的方法,myRedisClusterForHessian只不过是封装了集群下获取jedis的的方法。
核心方法如下:
jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
调用的底层实现

/**
 * Set the string value as value of the key. The string can't be longer than 1073741824 bytes (1
 * GB).
 * @param key
 * @param value
 * @param nxxx NX|XX, NX -- Only set the key if it does not already exist. XX -- Only set the key
 *          if it already exist.
 * @param expx EX|PX, expire time units: EX = seconds; PX = milliseconds
 * @param time expire time in the units of <code>expx</code>
 * @return Status code reply
 */
public String set(final String key, final String value, final String nxxx, final String expx,
    final long time) {
  checkIsInMultiOrPipeline();
  client.set(key, value, nxxx, expx, time);
  return client.getStatusCodeReply();
}

解释如下:
Key,锁的key(名称)
requestId,加锁的客户端id
nxxx NX|XX, NX – 如果不存在设置key,存在则不做; XX – 如果key存在才设置,不存在不做
expx EX|PX, EX—失效时间单位为秒,PX—失效时间单位为毫秒
time 失效时间长度
返回 OK 表示成功

就是通过uuid来给同一个key加锁,不同服务器,uuid不同,谁锁的,只能谁解锁。或者到达超时时间后自动解锁。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值