Skip to content

Commit 213cf6f

Browse files
authored
🐛 #3631 修复tryLockunlock中针对Key的序列化方式不一致导致无法unlock的问题
1 parent c8d84da commit 213cf6f

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/locks/RedisTemplateSimpleDistributedLock.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
import org.springframework.data.redis.core.script.DefaultRedisScript;
88
import org.springframework.data.redis.core.script.RedisScript;
99
import org.springframework.data.redis.core.types.Expiration;
10+
import org.springframework.data.redis.serializer.RedisSerializer;
1011

1112
import java.nio.charset.StandardCharsets;
1213
import java.util.Collections;
1314
import java.util.List;
15+
import java.util.Objects;
1416
import java.util.UUID;
1517
import java.util.concurrent.TimeUnit;
1618
import java.util.concurrent.locks.Condition;
@@ -70,8 +72,10 @@ public boolean tryLock() {
7072
value = UUID.randomUUID().toString();
7173
valueThreadLocal.set(value);
7274
}
73-
final byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
74-
final byte[] valueBytes = value.getBytes(StandardCharsets.UTF_8);
75+
RedisSerializer<String> keySerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
76+
RedisSerializer<String> valueSerializer = (RedisSerializer<String>) redisTemplate.getValueSerializer();
77+
final byte[] keyBytes = Objects.requireNonNull(keySerializer.serialize(key));
78+
final byte[] valueBytes = Objects.requireNonNull(valueSerializer.serialize(value));
7579
List<Object> redisResults = redisTemplate.executePipelined((RedisCallback<String>) connection -> {
7680
connection.set(keyBytes, valueBytes, Expiration.milliseconds(leaseMilliseconds), RedisStringCommands.SetOption.SET_IF_ABSENT);
7781
connection.get(keyBytes);

weixin-java-common/src/test/java/me/chanjar/weixin/common/util/locks/RedisTemplateSimpleDistributedLockTest.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package me.chanjar.weixin.common.util.locks;
22

33
import lombok.extern.slf4j.Slf4j;
4+
import org.jetbrains.annotations.NotNull;
45
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
56
import org.springframework.data.redis.core.StringRedisTemplate;
7+
import org.springframework.data.redis.serializer.StringRedisSerializer;
68
import org.testng.annotations.BeforeTest;
79
import org.testng.annotations.Test;
810

@@ -13,9 +15,10 @@
1315
import static org.testng.Assert.*;
1416

1517
@Slf4j
16-
@Test(enabled = false)
18+
@Test(enabled = true)
1719
public class RedisTemplateSimpleDistributedLockTest {
1820

21+
private static final String KEY_PREFIX = "System:";
1922
RedisTemplateSimpleDistributedLock redisLock;
2023

2124
StringRedisTemplate redisTemplate;
@@ -29,6 +32,28 @@ public void init() {
2932
connectionFactory.setPort(6379);
3033
connectionFactory.afterPropertiesSet();
3134
StringRedisTemplate redisTemplate = new StringRedisTemplate(connectionFactory);
35+
// 自定义序列化器,为 key 自动加前缀
36+
redisTemplate.setKeySerializer(new StringRedisSerializer() {
37+
@NotNull
38+
@Override
39+
public byte[] serialize(String string) {
40+
if (string == null) {
41+
return super.serialize(null);
42+
}
43+
// 添加前缀
44+
return super.serialize(KEY_PREFIX + string);
45+
}
46+
47+
@NotNull
48+
@Override
49+
public String deserialize(byte[] bytes) {
50+
String key = super.deserialize(bytes);
51+
if (key.startsWith(KEY_PREFIX)) {
52+
return key.substring(KEY_PREFIX.length());
53+
}
54+
return key;
55+
}
56+
});
3257
this.redisTemplate = redisTemplate;
3358
this.redisLock = new RedisTemplateSimpleDistributedLock(redisTemplate, 60000);
3459
this.lockCurrentExecuteCounter = new AtomicInteger(0);

0 commit comments

Comments
 (0)