Spring数据RedisTemplate,设置值时ttl不工作
Spring Data RedisTemplate, ttl is not working when setting a value
我想为存储在 Redis 中的密钥设置一个 ttl,我是通过以下方式完成的:
@Component
public class RedisBetgeniusMarketService implements BetgeniusMarketService {
private static final int DEFAULT_EVENTS_LIFE_TIME = 240;
@Value("${redis.events.lifetime}")
private long eventsLifeTime = DEFAULT_EVENTS_LIFE_TIME;
@Autowired
private RedisTemplate<String, Market> marketTemplate;
@Override
public Market findOne(Integer fixtureId, Long marketId) {
String key = buildKey(fixtureId, marketId);
return marketTemplate.boundValueOps(key).get();
}
@Override
public void save(Integer fixtureId, Market market) {
String key = buildKey(fixtureId, market.getId());
BoundValueOperations<String, Market> boundValueOperations = marketTemplate.boundValueOps(key);
boundValueOperations.expire(eventsLifeTime, TimeUnit.MINUTES);
boundValueOperations.set(market);
}
private String buildKey(Integer fixtureId, Long marketId) {
return "market:" + fixtureId + ":" + marketId;
}
}
但是,当我打印创建的密钥的 ttl 时,它等于 -1
。
请告诉我我做错了什么。
模板bean配置如下:
@Bean
public RedisTemplate<String, com.egalacoral.spark.betsync.entity.Market> marketTemplate(RedisConnectionFactory connectionFactory) {
final RedisTemplate<String, com.egalacoral.spark.betsync.entity.Market> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(com.egalacoral.spark.betsync.entity.Market.class));
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
我已经替换了 set()
和 expire()
方法,它开始工作了。
@Override
public void save(Integer fixtureId, Market market) {
String key = buildKey(fixtureId, market.getId());
BoundValueOperations<String, Market> boundValueOperations
= marketTemplate.boundValueOps(key);
boundValueOperations.set(market);
boundValueOperations.expire(eventsLifeTime, TimeUnit.MINUTES);
}
您需要以不同的顺序调用 expire(…)
和 set(…)
。 SET 命令删除之前应用的任何超时:
来自 http://redis.io/commands/set 的文档:
Set key to hold the string value. If key already holds a value, it is overwritten, regardless of its type. Any previous time to live associated with the key is discarded on successful SET operation.
在您的情况下,您只需将 expire(…)
和 set(…)
的顺序切换为 set(…)
和 expire(…)
.
@Override
public void save(Integer fixtureId, Market market) {
String key = buildKey(fixtureId, market.getId());
BoundValueOperations<String, Market> boundValueOperations = marketTemplate.boundValueOps(key);
boundValueOperations.set(market);
boundValueOperations.expire(eventsLifeTime, TimeUnit.MINUTES);
}
除此之外,您可以通过在一次调用中设置值和到期时间来改进代码。 ValueOperations
(RedisOperations.opsForValue()
) 提供了一个set
方法,用签名
设置密钥和超时
void set(K key, V value, long timeout, TimeUnit unit);
您也可以尝试在给定的特定时间内使 Redis 中的密钥过期
redisTemplate.opsForValue().set(key, value, 1, TimeUnit.MINUTES);
我想为存储在 Redis 中的密钥设置一个 ttl,我是通过以下方式完成的:
@Component
public class RedisBetgeniusMarketService implements BetgeniusMarketService {
private static final int DEFAULT_EVENTS_LIFE_TIME = 240;
@Value("${redis.events.lifetime}")
private long eventsLifeTime = DEFAULT_EVENTS_LIFE_TIME;
@Autowired
private RedisTemplate<String, Market> marketTemplate;
@Override
public Market findOne(Integer fixtureId, Long marketId) {
String key = buildKey(fixtureId, marketId);
return marketTemplate.boundValueOps(key).get();
}
@Override
public void save(Integer fixtureId, Market market) {
String key = buildKey(fixtureId, market.getId());
BoundValueOperations<String, Market> boundValueOperations = marketTemplate.boundValueOps(key);
boundValueOperations.expire(eventsLifeTime, TimeUnit.MINUTES);
boundValueOperations.set(market);
}
private String buildKey(Integer fixtureId, Long marketId) {
return "market:" + fixtureId + ":" + marketId;
}
}
但是,当我打印创建的密钥的 ttl 时,它等于 -1
。
请告诉我我做错了什么。
模板bean配置如下:
@Bean
public RedisTemplate<String, com.egalacoral.spark.betsync.entity.Market> marketTemplate(RedisConnectionFactory connectionFactory) {
final RedisTemplate<String, com.egalacoral.spark.betsync.entity.Market> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(com.egalacoral.spark.betsync.entity.Market.class));
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
我已经替换了 set()
和 expire()
方法,它开始工作了。
@Override
public void save(Integer fixtureId, Market market) {
String key = buildKey(fixtureId, market.getId());
BoundValueOperations<String, Market> boundValueOperations
= marketTemplate.boundValueOps(key);
boundValueOperations.set(market);
boundValueOperations.expire(eventsLifeTime, TimeUnit.MINUTES);
}
您需要以不同的顺序调用 expire(…)
和 set(…)
。 SET 命令删除之前应用的任何超时:
来自 http://redis.io/commands/set 的文档:
Set key to hold the string value. If key already holds a value, it is overwritten, regardless of its type. Any previous time to live associated with the key is discarded on successful SET operation.
在您的情况下,您只需将 expire(…)
和 set(…)
的顺序切换为 set(…)
和 expire(…)
.
@Override
public void save(Integer fixtureId, Market market) {
String key = buildKey(fixtureId, market.getId());
BoundValueOperations<String, Market> boundValueOperations = marketTemplate.boundValueOps(key);
boundValueOperations.set(market);
boundValueOperations.expire(eventsLifeTime, TimeUnit.MINUTES);
}
除此之外,您可以通过在一次调用中设置值和到期时间来改进代码。 ValueOperations
(RedisOperations.opsForValue()
) 提供了一个set
方法,用签名
void set(K key, V value, long timeout, TimeUnit unit);
您也可以尝试在给定的特定时间内使 Redis 中的密钥过期
redisTemplate.opsForValue().set(key, value, 1, TimeUnit.MINUTES);