-
-
Notifications
You must be signed in to change notification settings - Fork 9.1k
bugfix: 如果RedisTemplate指定KeySerializer,可能会导致加锁成功,无法解锁 #3890
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -93,9 +93,11 @@ public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { | |
| @Override | ||
| public void unlock() { | ||
| if (valueThreadLocal.get() != null) { | ||
| // 提示: 必须指定returnType, 类型: 此处必须为Long, 不能是Integer | ||
| RedisScript<Long> script = new DefaultRedisScript<>("if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end", Long.class); | ||
| redisTemplate.execute(script, Collections.singletonList(key), valueThreadLocal.get()); | ||
| redisTemplate.executePipelined((RedisCallback<String>) connection -> { | ||
| connection.eval("if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end".getBytes(), | ||
| ReturnType.INTEGER, 1, key.getBytes(), valueThreadLocal.get().getBytes()); | ||
| return null; | ||
| }); | ||
|
Comment on lines
+96
to
+100
|
||
| valueThreadLocal.remove(); | ||
| } | ||
|
Comment on lines
94
to
102
|
||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里使用 key.getBytes()/valueThreadLocal.get().getBytes() 会绕过 StringRedisTemplate 的 key/value serializer(尤其是自定义 keySerializer 会加前缀的场景),可能再次导致“加锁/解锁使用的 Redis key 不一致”并解锁失败。建议改为使用 redisTemplate 的序列化器对 key/value 做 serialize(或恢复使用 RedisScript + redisTemplate.execute 的写法,以保持与 opsForValue() 一致的序列化行为)。