Spring Data RedisTemplate,设置值时ttl不起作用
Posted
技术标签:
【中文标题】Spring Data RedisTemplate,设置值时ttl不起作用【英文标题】:Spring Data RedisTemplate, ttl is not working when setting a value 【发布时间】:2016-11-24 23:00:12 【问题描述】:我想为存储在 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;
【问题讨论】:
【参考方案1】:您需要以不同的顺序调用expire(…)
和set(…)
。 SET 命令删除之前应用的任何超时:
来自http://redis.io/commands/set的文档:
设置键来保存字符串值。如果 key 已经包含一个值,则无论其类型如何,都会将其覆盖。在成功的 SET 操作后,任何先前与该键关联的生存时间都将被丢弃。
在您的情况下,您只需将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);
【讨论】:
感谢详细解答。【参考方案2】:我已经替换了 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);
【讨论】:
【参考方案3】:您也可以尝试使 Redis 中的密钥在给定的特定时间过期
redisTemplate.opsForValue().set(key, value, 1, TimeUnit.MINUTES);
【讨论】:
以上是关于Spring Data RedisTemplate,设置值时ttl不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Spring中使用RedisTemplate操作Redis(spring-data-redis)
Spring中使用RedisTemplate操作Redis(spring-data-redis)
Spring data redis使用java config配置redisTemplate(解决多个redis数据源问题)
Spring data redis使用java config配置redisTemplate(解决多个redis数据源问题)