🐛 #3631 修复tryLock和unlock中针对Key的序列化方式不一致导致无法unlock的问题
This commit is contained in:
@@ -7,10 +7,12 @@ import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
import org.springframework.data.redis.core.script.RedisScript;
|
||||
import org.springframework.data.redis.core.types.Expiration;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
@@ -70,8 +72,10 @@ public class RedisTemplateSimpleDistributedLock implements Lock {
|
||||
value = UUID.randomUUID().toString();
|
||||
valueThreadLocal.set(value);
|
||||
}
|
||||
final byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
|
||||
final byte[] valueBytes = value.getBytes(StandardCharsets.UTF_8);
|
||||
RedisSerializer<String> keySerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
|
||||
RedisSerializer<String> valueSerializer = (RedisSerializer<String>) redisTemplate.getValueSerializer();
|
||||
final byte[] keyBytes = Objects.requireNonNull(keySerializer.serialize(key));
|
||||
final byte[] valueBytes = Objects.requireNonNull(valueSerializer.serialize(value));
|
||||
List<Object> redisResults = redisTemplate.executePipelined((RedisCallback<String>) connection -> {
|
||||
connection.set(keyBytes, valueBytes, Expiration.milliseconds(leaseMilliseconds), RedisStringCommands.SetOption.SET_IF_ABSENT);
|
||||
connection.get(keyBytes);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package me.chanjar.weixin.common.util.locks;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -13,9 +15,10 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
@Slf4j
|
||||
@Test(enabled = false)
|
||||
@Test(enabled = true)
|
||||
public class RedisTemplateSimpleDistributedLockTest {
|
||||
|
||||
private static final String KEY_PREFIX = "System:";
|
||||
RedisTemplateSimpleDistributedLock redisLock;
|
||||
|
||||
StringRedisTemplate redisTemplate;
|
||||
@@ -29,6 +32,28 @@ public class RedisTemplateSimpleDistributedLockTest {
|
||||
connectionFactory.setPort(6379);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
StringRedisTemplate redisTemplate = new StringRedisTemplate(connectionFactory);
|
||||
// 自定义序列化器,为 key 自动加前缀
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer() {
|
||||
@NotNull
|
||||
@Override
|
||||
public byte[] serialize(String string) {
|
||||
if (string == null) {
|
||||
return super.serialize(null);
|
||||
}
|
||||
// 添加前缀
|
||||
return super.serialize(KEY_PREFIX + string);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String deserialize(byte[] bytes) {
|
||||
String key = super.deserialize(bytes);
|
||||
if (key.startsWith(KEY_PREFIX)) {
|
||||
return key.substring(KEY_PREFIX.length());
|
||||
}
|
||||
return key;
|
||||
}
|
||||
});
|
||||
this.redisTemplate = redisTemplate;
|
||||
this.redisLock = new RedisTemplateSimpleDistributedLock(redisTemplate, 60000);
|
||||
this.lockCurrentExecuteCounter = new AtomicInteger(0);
|
||||
|
||||
Reference in New Issue
Block a user