设为首页 加入收藏

TOP

Redis分布式锁常见坑点分析(三)
2023-07-25 21:40:08 】 浏览:37
Tags:Redis 常见坑
ss); Long execute = (Long) redisTemplate.execute(redisScript, Collections.singletonList(key), nanoId); boolean flag = execute != null && execute == 1; if (flag) { if (executorServiceThreadLocal.get() != null) { ThreadUtil.shutdownAndAwaitTermination(executorServiceThreadLocal.get()); } } return flag; } private String buildLuaLockScript() { return """ local key = KEYS[1] local value = ARGV[1] local time_out = ARGV[2] local result = redis.call('get', key) if result == value then return 1; end local lock_result = redis.call('setnx', key, value) if tonumber(lock_result) == 1 then redis.call('expire', key, time_out) return 1; else return 0; end """; } private String buildLuaUnLockScript() { return """ local key = KEYS[1] local value = ARGV[1] local result = redis.call('get', key) if result ~= value then return 0; else redis.call('del', key) end return 1; """; } private String buildLuaRenewScript() { return """ local key = KEYS[1] local value = ARGV[1] local timeout = ARGV[2] local result = redis.call('get', key) if result ~= value then return 2; end local ttl = redis.call('ttl', key) if tonumber(ttl) < tonumber(timeout) / 2 then redis.call('expire', key, timeout) return 1; else return 0; end """; } }

加锁逻辑:这里我把加锁逻辑分解成三步展示给大家

  • 加锁前:先判断当前线程是否存在请求ID,不存在则生成,存在就直接使用
  • 加锁中:通过 lua 脚本执行原子加锁操作,
    加锁时先判断当前线程ID与加锁 key 得 value 是否相等,相等则是同一个线程的锁重入,直接返加锁成功。不相等则设置加锁 value 为请求ID以及过期时间。
  • 加锁后:启动一个定时任务,每隔 过期时间 / 3 秒后执行一次续期操作,发现锁剩余时间不足 过期时间 / 2 秒后,通过 lua 脚本进行续期操作。

解锁逻辑:这里我把解锁逻辑分解成两步展示给大家

  • 解锁中:通过 lua 脚本执行解锁操作,先判断加锁 key 的 value 是否与自身请求ID相同,相同则让解锁,不相同则不让解锁。
  • 解锁后:删除定时任务。

五、总结

其实本文得核心逻辑有许多都是参考 Redission 客户端而写,对于这些常见得坑点,博主结合自身思考,业界知识总结并自己实现一个分布式锁得工具类。希望大家看了有所收获,对日常业务中 Redis 分布式锁的使用能有更深的理解。

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇1.2复习了一下MySQL的索引 下一篇docker学习(dockerfile打jar包为..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目