【发布时间】:2019-10-30 13:32:39
【问题描述】:
我遇到了一个有趣的 Spring Boot Cache eviction 场景,其中我有一个使用 @Cacheable("users") 的无参数方法,而我有另一个使用 @CacheEvict("users") 的方法。
@Cacheable(value = "users")
public List<String> getUsers() {
return myRepo.getUsers();
}
@CacheEvict(value = "users")
public void createUser(User user) {
myRepo.createUser(user);
}
我的假设是,每当我调用 createUser() 方法时,“用户”缓存将被驱逐,而下次我调用 getUsers() 时,它将调用 myRepo.getUsers()。但我注意到“用户”缓存没有被驱逐,myRepo.getUsers() 没有被调用。
经过反复试验,我设法通过指定 key 解决了这个问题,如下所示:
@Cacheable(value = "users", key="'users'")
public List<String> getUsers() {
return myRepo.getUsers();
}
@CacheEvict(value = "users", key="'users'")
public void createUser(User user) {
myRepo.createUser(user);
}
这是预期的行为吗?它不应该通过提及 @CacheEvict(value = "users") 来驱逐“用户”缓存中的所有条目吗?
【问题讨论】:
-
它是否适用于带有一些参数的方法?问题标题似乎具有误导性
-
你试过@CacheEvict(value = "users" allEntries = true)
-
添加 allEntries = true 可以解决问题,但如果我们不指定键,它不应该全部驱逐吗?
-
缓存是基于key或者生成的key进行缓存。它将按原样缓存方法的结果。因此,在您的情况下,它将存储
List的User对象。它不会将单个用户存储为键/值对。默认情况下,缓存驱逐将驱逐与被更新相同的元素(基于键)。由于您有不同的密钥,因此不会驱逐任何内容。这就是您通过硬编码注释中的键所看到的。如果没有匹配项清空整个缓存,则默认值不是,默认值是删除匹配的元素。为什么它应该驱逐没有缓存的东西? -
感谢 M. Deinum 的澄清。
标签: java spring spring-boot caching