public static boolean lock(String key,String lockValue,int expire){
if(null == key){
return false;
}
try {
Jedis jedis = getJedisPool().getResource();
String res = jedis.set(key,lockValue,"NX","EX",expire);
jedis.close();
return res!=null && res.equals("OK");
} catch (Exception e) {
return false;
}
}
複製代碼
add.luaredis
local lockKey = KEYS[1]
local lockValue = KEYS[2]
-- setnx info
local result_1 = redis.call('SETNX', lockKey, lockValue)
if result_1 == true
then
local result_2= redis.call('SETEX', lockKey,3600, lockValue)
return result_1
else
return result_1
end
複製代碼
/**
* 獲取lua結果
* @param key
* @param value
* @return
*/
public Boolean luaExpress(String key,String value) {
DefaultRedisScript<Boolean> lockScript = new DefaultRedisScript<Boolean>();
lockScript.setScriptSource(
new ResourceScriptSource(new ClassPathResource("add.lua")));
lockScript.setResultType(Boolean.class);
// 封裝參數
List<Object> keyList = new ArrayList<Object>();
keyList.add(key);
keyList.add(value);
Boolean result = (Boolean) redisTemplate.execute(lockScript, keyList);
return result;
}
複製代碼
unlock.luaspring
if redis.call('get', KEYS[1]) == ARGV[1]
then
return redis.call('del', KEYS[1])
else
return 0
end
複製代碼
private static final Long lockReleaseOK = 1L;
static String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";// lua腳本,用來釋放分佈式鎖
public static boolean releaseLock(String key ,String lockValue){
if(key == null || lockValue == null) {
return false;
}
try {
Jedis jedis = getJedisPool().getResource();
Object res =jedis.eval(luaScript,Collections.singletonList(key),Collections.singletonList(lockValue));
jedis.close();
return res!=null && res.equals(lockReleaseOK);
} catch (Exception e) {
return false;
}
}
複製代碼
spring-data-redis的版本儘可能高版本,2.0如下的connection.set是沒有返回值的。bash
@Component
public class RedisLock {
@Resource
private RedisTemplate<String, Object> redisTemplate;
//加鎖
public Boolean setNX(final String key, final String requestId, final long expirationTime, final TimeUnit timeUnit) {
return redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.set(key.getBytes(), (value == null ? "" : value).getBytes(),
Expiration.from(expirationTime, timeUnit),
RedisStringCommands.SetOption.ifAbsent()));
}
//釋放鎖
public Boolean releaseLock(String key, String requestId) {
return (Boolean) redisTemplate.execute((RedisCallback<Boolean>) connection -> {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Boolean result = connection.eval(script.getBytes(), ReturnType.BOOLEAN, 1, key.getBytes(), requestId.getBytes());
return result;
});
}
}
複製代碼