当前位置: 首页 > 知识库问答 >
问题:

Spring@cacheable:错误时保留旧值

潘修为
2023-03-14
  1. 调用可缓存方法->返回有效结果
  2. 结果将由Spring@Cacheable后端缓存
  3. Spring使缓存无效,因为它已过期(例如,1小时的TTL)
  4. 再次调用可缓存方法->返回异常/空值!
  5. 旧的结果将被再次缓存,因此,方法的未来调用将返回有效结果

这怎么可能?

共有1个答案

司寇星海
2023-03-14

如果@cacheable方法抛出一个异常,您需要为旧值提供服务,只需对Google Guava进行最小的扩展,就可以轻松实现这一要求。

使用以下示例配置

@Configuration
@EnableWebMvc
@EnableCaching
@ComponentScan("com.yonosoft.poc.cache")
public class ApplicationConfig extends CachingConfigurerSupport {
    @Bean
    @Override
    public CacheManager cacheManager() {
        SimpleCacheManager simpleCacheManager = new SimpleCacheManager();

        GuavaCache todoCache = new GuavaCache("todo", CacheBuilder.newBuilder()
            .refreshAfterWrite(10, TimeUnit.MINUTES)
            .maximumSize(10)
            .build(new CacheLoader<Object, Object>() {
                @Override
                public Object load(Object key) throws Exception {
                    CacheKey cacheKey = (CacheKey)key;
                    return cacheKey.method.invoke(cacheKey.target, cacheKey.params);
                }
            }));

        simpleCacheManager.setCaches(Arrays.asList(todoCache));

        return simpleCacheManager;
    }

    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                return new CacheKey(target, method, params);
            }
        };
    }

    private class CacheKey extends SimpleKey {
        private static final long serialVersionUID = -1013132832917334168L;
        private Object target;
        private Method method;
        private Object[] params;

        private CacheKey(Object target, Method method, Object... params) {
            super(params);
            this.target = target;
            this.method = method;
            this.params = params;
        }
    }
}

CacheKey的唯一目的是公开SimpleKey属性。Guavas refreshAfterWrite将配置刷新时间,而不会使缓存条目过期。如果用@cacheable注释的方法引发异常,则缓存将继续为旧值提供服务,直到因maximumsize而被逐出或被成功方法响应中的新值替换为止。您可以将refreshAfterwriteexpireAfterAccessexpireAfterAccess结合使用。

 类似资料:
  • 我正在使用资源设置TextView的一些背景样式(特定边框等)。无法在资源中设置背景颜色,因为它可能会根据某些规则而变化。 然而,以后使用该资源时,即使是在完全不同的片段中,也会重用最后指定的颜色。看起来颜色被分配给了资源,而不仅仅是在TextView中,并且在整个应用程序中重复使用。然而,重要的是要注意,不同的TextViews按预期显示不同的背景颜色。 这里的问题是,资源的任何其他未来使用都是

  • 当我执行这个程序时,一切都很好:

  • 我从ESLint获得此错误: 根据该代码: 我已经尝试过删除并重新安装所有npm软件包(如本文所建议的),但没有效果。

  • 问题内容: 我从ESLint收到此错误: 从此代码: 我试着删除并重新安装所有NPM包,但无济于事。 问题答案: ESLint默认为ES5语法检查。您将要覆盖到最新的受支持的JavaScript版本。 尝试将文件添加到您的项目。在里面: 希望这会有所帮助。 编辑:我也发现了这个例子可能会有所帮助。

  • 问题内容: 我和之间有关系 所以当我尝试持久化对象时 我懂了 如您所见,它尝试插入正确的值,但是以某种方式将其标记为语法错误。我认为它缺少左右的单引号,但是由于它是在后台进行查询的,所以我不知道如何解决它。请注意,我对同一项目中的其他实体执行了完全相同的操作,并且工作正常。太沮丧了!! 问题答案: GROUP确实是保留的关键字,您必须对其进行转义。在JPA 2.0中,有一种标准化的方法来指定分隔标

  • 以下是Tensorflow站点的示例;我试图在Ubuntu python 2.7环境中重新训练初始模型的最后一层。在命令下运行时 $bazel build/home/incept/tensorflow/tensorflow/examples/image_再培训:再培训 有没有解决这个问题的建议?举个例子 $bazel build tensorflow/示例/图像再培训:再培训