【问题标题】:Collisions may occur when using Spring @Cacheable and SimpleKeyGenerator使用 Spring @Cacheable 和 SimpleKeyGenerator 时可能会发生冲突
【发布时间】:2016-05-11 10:04:03
【问题描述】:

当我使用@Cacheable 并使用相同的参数调用不同的方法时,它会生成相同的密钥。 SimpleKeyGenerator 生成的密钥没有缓存名称。

我使用 spring-boot 1.3.2 和 spring 4.2.4。

这是一个示例:

@Component
public static class CacheableTestClass {

    @Cacheable(cacheNames = "test-cacheproxy-echo1")
    public String echo1(String text) {
        return text;
    }

    @Cacheable(cacheNames = "test-cacheproxy-echo2")
    public String echo2(String text) {
        return "Another " + text;
    }
}

并运行测试:

assertEquals("OK", cacheableTestClass.echo1("OK"));
assertEquals("Another OK", cacheableTestClass.echo2("OK")); // Failure: expected 'Another OK', actual 'OK'.

那么,有没有办法解决这个问题? 非常感谢。

更新

这是我的CacheManager 配置。

@Bean
@ConditionalOnMissingBean(name = "cacheRedisTemplate")
public RedisTemplate<Object, Object> cacheRedisTemplate(
        RedisConnectionFactory redisConnectionFactory)
        throws UnknownHostException {
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    template.setHashKeySerializer(template.getKeySerializer());
    return template;
}

@Bean
public RedisCacheManager cacheManager(@Qualifier("cacheRedisTemplate")  RedisTemplate<Object, Object> cacheRedisTemplate) {
    RedisCacheManager cacheManager = new RedisCacheManager(cacheRedisTemplate);
    cacheManager.setDefaultExpiration(
            redisCacheProperties().getDefaultExpiration());
    cacheManager.setExpires(redisCacheProperties().getExpires());
    return cacheManager;
}

【问题讨论】:

  • 发布 CacheManager 的配置。从您的代码 sn-ps 中,键不应该因为您使用不同的缓存名称而发生冲突
  • @ekemchitsiga 更新我的CacheManager 配置。

标签: spring spring-boot spring-4 spring-cache spring-data-redis


【解决方案1】:

这与 SimpleKeyGenerator 无关,但这是一个特定于 redis 的问题,它不使用缓存的名称作为它用于存储值的键的判别。

您需要在您的RedisCacheManager 上调用setUsePrefix(true)。这就是 Spring Boot 在为您自动配置缓存管理器时所做的事情。请注意,它应该是默认设置,我们正在讨论如何在未来版本中改进开箱即用的体验

【讨论】:

  • 如果我理解正确,我绝对同意这应该是默认模式。此外,如果RedisCacheManager 忽略它们,我不明白cacheNames 的意义何在
  • 默认情况下会忽略它们,这是一个错误。
  • 谢谢,我不知道,因为碰撞而出错。现在我在创建RedisCacheManager 时设置&lt;property name="usePrefix" value="true"/&gt;(是的,我仍在使用xml :)
  • @StephaneNic​​oll 这个问题我们有什么进展吗?
  • 他们重写了 Redis 缓存管理器,我相信它已经修复了。您可以在#spring-data gitter 频道上提问。
猜你喜欢
  • 2017-06-29
  • 1970-01-01
  • 1970-01-01
  • 2010-09-16
  • 2012-09-03
  • 2014-07-08
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多