Spring Data RedisTemplate,ttl在设置值时不起作用

时间:2016-07-21 11:13:28

标签: redis spring-data-redis

我想为存储在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;
    } 

3 个答案:

答案 0 :(得分:5)

您需要以不同的顺序致电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);
}

除此之外,您可以通过在一次调用中设置值和到期来改进代码。 ValueOperationsRedisOperations.opsForValue())提供set方法,用签名设置密钥和超时

void set(K key, V value, long timeout, TimeUnit unit);

答案 1 :(得分:1)

我已经替换了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);
    }

答案 2 :(得分:0)

您也可以尝试在给定的特定时间内使Redis中的密钥失效

docker run --net=host ... gusaul/grpcox