天行健861010 / 分布式 / redis实现分布式锁

分享

   

redis实现分布式锁

2019-10-04  天行健861...
package com.hd.common.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import java.util.Collections;
import java.util.UUID;

/**
* https://blog.csdn.net/yb223731/article/details/90349502
* @author Administrator
* @create 2019/10/4 21:10
*
* 要点:
* 1,互斥性
* 2,不会发生死锁(必须设置锁的过期时间,这个根据业务情况来定,如果业务执行时间长,就设置长点;执行时间短,就设置短点)
* 3,容错性
* 4,加锁和解锁必须是同一人(必须判断value和requestId相同,才能删除)
*
* 注意:
* 1,原子性问题 多行redis命令,一定注意考虑原子性问题
*/
@Component
public class RedisLockUtil {
@Autowired
private Jedis redis;
public boolean tryRedisLock(String lockKey,String requestId,Long expireTime){
if("OK".equals(redis.set(lockKey,requestId,"NX","EX",expireTime))){
return true;
}
return false;
}
public boolean releaseRedisLock(String lockKey,String requestId){
String script="if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
Object result = redis.eval(script, Collections.singletonList(lockKey),Collections.singletonList(requestId));
if("1".equals(result)){
return true;
}
return false;
}
/**
* 使用分布式锁的案例
* @param key
* @return
*/
public String getProduct(String key){
String value = redis.get(key);
if(value==null){
String lockKey = "lockKey:"+key;
String requestId = UUID.randomUUID().toString();
Boolean lock = tryRedisLock(lockKey,requestId,30L);
try {
if(lock){
value = redis.get(key);
if(value==null){
String dbValue = getFromDb();
if(dbValue==null){
value = key+" not exist";
redis.set(key,value,"XX","EX",30);
}else {
value= dbValue;
redis.set(key,value,"XX","EX",5*60);
}
}
}
}finally {
if(lock){
releaseRedisLock(lockKey,requestId);
}
}
}
return value;
}

public static String getFromDb() {
return null;
}
}

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多

    ×
    ×

    ¥.00

    微信或支付宝扫码支付:

    开通即同意《个图VIP服务协议》

    全部>>