基于Redis实现分布式锁之防误删非自己的锁(lua版本)
使用lua需要配置环境,但是Redis已经继承了Lua,所以使用Redis可以不用安装Lua脚本,其本身提供了对lua的支持
主要通过 指令 eval script numKeys key.. arg..
redis输出的不是lua脚本的输出,而是lua脚本的的返回值
//基于 Redis 实现分布式锁 public void testLock() { //加锁 String uuid = UUID.randomUUID().toString(); Boolean lock = this.redisTemplate.opsForValue().setIfAbsent("lock", uuid,3,TimeUnit.SECONDS); //setIfAbsent 对应 setnx,只能设置为空的key if (!lock){ try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } this.testLock(); }else{ //设置过期时间 //this.redisTemplate.expire("lock",3,TimeUnit.MILLISECONDS); //获取锁,执行业务操作 String num = this.redisTemplate.opsForValue().get("num"); if (StringUtils.isBlank(num)){ this.redisTemplate.opsForValue().set("num","1"); return; } int i = Integer.parseInt(num); this.redisTemplate.opsForValue().set("num",String.valueOf(++i)); //释放锁(使用lua脚本) String script = "if redis.call('get',KEYS[1]) == ARGV[1]" + "then " + " retuen redis.call('del',KEYS[1]) " + "else " + " return 0 " + "end"; this.redisTemplate.execute(new DefaultRedisScript<>(script,Boolean.class), Arrays.asList("lock"),uuid); // if (StringUtils.equals(uuid,this.redisTemplate.opsForValue().get("lock"))){ // this.redisTemplate.delete("lock"); // } } }

浙公网安备 33010602011771号