通常部署的服务都是在多台服务器上,不会只有一台。那么在分布式环境下,就会遇到共享资源的问题。比如一个人只能有一条记录,下次进来就只能修改,而不是再新增。
如果只有一台服务器,可以使用多线程下的单例模式来控制,但是分布式下,就不管用了。
有三种方式,一是使用数据库的乐观锁,二是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不同,谁锁的,只能谁解锁。或者到达超时时间后自动解锁。