集群方式下的java Redis锁 lua脚本
下面说一下集群方式redis 下的原子锁 带超时时间java 代码如下:
List<String> keys =Collections.singletonList("test_key1");
System.out.println("打印前 ::"+jedisCluster.get("test_key1"));
//获取lua 脚本这里你可以所以 我是放在META-INF/scripts/redis/test.lua 路径下,
//获取到之后放到字符串String LUA 里边
URL url = Resources.getResource("META-INF/scripts/redis/test.lua");
List<String> lines = Resources.asCharSource(url, Charsets.UTF_8).readLines();
List<String> args = new ArrayList<>(2);
// 以当前时间戳作为value
args.add(DateUtil.dateToString(new Date(), DateUtil.DEFAULT_TIMESTAMP_FORMAT));
// 超时时间(单位秒)
long lockTimeMs = 5;
args.add(String.valueOf(lockTimeMs));
LUA = "";
lines.forEach(line->{
LUA += (line + "\n");
});
Object result =jedisCluster.eval(LUA, keys, args);
//这是另一种方式 作为一个 补充
jedisCluster.set("lockKey", "lockVal", "NX", "PX", 1000);
//注意这里是用另外一种方式,因为我们redis 大部分是集群方式,很少有单机
//我们这里可以灵活判断 具体走单机还是集群 进行 redis 家所
String result1 = (String)stringRedisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection) throws DataAccessException {
Object nativeConnection = connection.getNativeConnection();
// 集群模式和单点模式虽然执行脚本的方法一样,但是没有共同的接口,所以只能分开执行
// 集群
if (nativeConnection instanceof JedisCluster) {
return (String) ((JedisCluster) nativeConnection).eval(LUA, keys,args);
}
// 单点
else if (nativeConnection instanceof Jedis) {
return (String) ((Jedis) nativeConnection).eval(LUA, keys, args);
}
return null;
}
});
System.out.println("打印::result "+result.toString());
System.out.println("打印getValueByKey::"+jedisCluster.get("test_key1"));
long tll =jedisCluster.ttl("test_key1");
System.out.println("打印::超时时间 单位秒"+tll);
Thread.sleep(6000);
System.out.println("打印::"+jedisCluster.get("test_key1"));
Lua脚本如下:
if redis.pcall('GET',KEYS[1]) == false then
if redis.pcall("SET", KEYS[1], ARGV[1]) =='OK' then
end
return redis.pcall("EXPIRE", KEYS[1], ARGV[2])
else
return redis.pcall('TTL',KEYS[1])
end
另一种写法:
if redis.pcall('EXISTS',KEYS[1]) == 0 then
return redis.pcall('SET', KEYS[1], ARGV[1], 'EX', ARGV[2])
else
return redis.pcall('TTL',KEYS[1])
end