Redisson如何保证解锁的线程一定是加锁的线程?

1 个回答

  • 兽神
    倾城倩影销魂态,如此佳人何处寻。
    Redisson 通过 **UUID + 线程标识** 的方式,确保解锁操作只能由加锁的线程执行,避免误解锁问题。 ### **1. Redisson 分布式锁加锁机制** 1. **使用 `setNx()`(`SET key value NX PX time`)加锁** - `key`:锁的名称。 - `value`:`UUID + 线程 ID`(确保唯一性)。 - `NX`:仅当 key 不存在时才设置,避免被覆盖。 - `PX time`:设置锁的自动过期时间,防止死锁。 **示例** ```lua SET lockKey <uuid>:<threadId> NX PX 30000 ``` 这里的 `value` 是唯一标识,例如 `550e8400-e29b-41d4-a716-446655440000:1`。 ### **2. 解锁时的线程校验** 1. **获取锁的 value** - 读取 `lockKey` 的 `value`(UUID + 线程 ID)。 2. **判断当前线程是否持有锁** - 只有与 `UUID + 线程 ID` 匹配的线程才允许解锁。 3. **执行 `DEL` 删除锁** - 只有匹配成功时才删除,避免误删其他线程的锁。 **Redisson 使用 Lua 脚本原子性校验** ```lua if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end ``` - `KEYS[1]`:锁的 key。 - `ARGV[1]`:当前线程的 `UUID + 线程 ID`。 - 只有 `get` 返回值匹配时,才执行 `del`。 ### **3. 为什么需要 UUID?** - 线程 ID 只能区分 **同一 JVM 内的线程**,不能区分 **不同 JVM 的实例**。 - **UUID 确保唯一性**,即使多个 JVM 节点上使用相同的线程 ID,也不会误解锁。 ### **4. 续期机制** - Redisson 默认 **锁超时自动续期**(`watchdog` 机制)。 - 如果锁仍然被持有,则定期续期,防止锁意外释放。 - 续期时也会检查 `UUID + 线程 ID`,确保是同一个持有者在续期。 ### **5. 结论** Redisson 依赖 **UUID + 线程 ID** 作为唯一标识,**通过 Lua 脚本原子检查** 确保只有持有锁的线程才能解锁,从而防止误解锁。
    发布于 2025-03-10 13:16 •IP属地 新疆
    举报
    评论
    收藏