🐛 #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.DefaultRedisScript;
|
||||||
import org.springframework.data.redis.core.script.RedisScript;
|
import org.springframework.data.redis.core.script.RedisScript;
|
||||||
import org.springframework.data.redis.core.types.Expiration;
|
import org.springframework.data.redis.core.types.Expiration;
|
||||||
|
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.Condition;
|
import java.util.concurrent.locks.Condition;
|
||||||
@@ -70,8 +72,10 @@ public class RedisTemplateSimpleDistributedLock implements Lock {
|
|||||||
value = UUID.randomUUID().toString();
|
value = UUID.randomUUID().toString();
|
||||||
valueThreadLocal.set(value);
|
valueThreadLocal.set(value);
|
||||||
}
|
}
|
||||||
final byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
|
RedisSerializer<String> keySerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
|
||||||
final byte[] valueBytes = value.getBytes(StandardCharsets.UTF_8);
|
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 -> {
|
List<Object> redisResults = redisTemplate.executePipelined((RedisCallback<String>) connection -> {
|
||||||
connection.set(keyBytes, valueBytes, Expiration.milliseconds(leaseMilliseconds), RedisStringCommands.SetOption.SET_IF_ABSENT);
|
connection.set(keyBytes, valueBytes, Expiration.milliseconds(leaseMilliseconds), RedisStringCommands.SetOption.SET_IF_ABSENT);
|
||||||
connection.get(keyBytes);
|
connection.get(keyBytes);
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package me.chanjar.weixin.common.util.locks;
|
package me.chanjar.weixin.common.util.locks;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
@@ -13,9 +15,10 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import static org.testng.Assert.*;
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Test(enabled = false)
|
@Test(enabled = true)
|
||||||
public class RedisTemplateSimpleDistributedLockTest {
|
public class RedisTemplateSimpleDistributedLockTest {
|
||||||
|
|
||||||
|
private static final String KEY_PREFIX = "System:";
|
||||||
RedisTemplateSimpleDistributedLock redisLock;
|
RedisTemplateSimpleDistributedLock redisLock;
|
||||||
|
|
||||||
StringRedisTemplate redisTemplate;
|
StringRedisTemplate redisTemplate;
|
||||||
@@ -29,6 +32,28 @@ public class RedisTemplateSimpleDistributedLockTest {
|
|||||||
connectionFactory.setPort(6379);
|
connectionFactory.setPort(6379);
|
||||||
connectionFactory.afterPropertiesSet();
|
connectionFactory.afterPropertiesSet();
|
||||||
StringRedisTemplate redisTemplate = new StringRedisTemplate(connectionFactory);
|
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.redisTemplate = redisTemplate;
|
||||||
this.redisLock = new RedisTemplateSimpleDistributedLock(redisTemplate, 60000);
|
this.redisLock = new RedisTemplateSimpleDistributedLock(redisTemplate, 60000);
|
||||||
this.lockCurrentExecuteCounter = new AtomicInteger(0);
|
this.lockCurrentExecuteCounter = new AtomicInteger(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user