在生产环境中绕过@Cacheable注解进行调试

发布于 2024-11-09 03:40:47 字数 409 浏览 0 评论 0原文

我正在开发一个基于 Spring 的新项目,我想知道是否要使用 Spring 3.1 或 ehcache-spring-annotation 项目,您将如何实现“按需”绕过缓存机制的机制,例如用于生产调试。

假设我的应用程序仅提供 REST 请求,有时,我希望通过一次调用(我手动进行)直接从“DB”(或任何后端)获取数据,并避免在数据库上进行任何缓存方式(任何缓存)。当调用正在运行时,我真的不介意它是否用刚刚从数据库获得的内容重新填充缓存......

我想听听您对如何实现这一点的想法。

预先感谢您的任何指导,

肯。

I'm working on a new Spring based project and I was wondering, if i were to use the @Cacheable annotation found in Spring 3.1 or in the ehcache-spring-annotation project, how would you go about implementing a mechanism for bypassing the cache mechanism "on demand", e.g. for production debugging.

Let's say my application serves only REST requests, on occasion, i would like, for a single call (that i manually make) to get data directly from the "DB" (or what ever backend there is) and avoid and any caching on the way (any caching). While the call is running, I don't really mind if it re-populates the cache with what it just got from the db...

I would like to hear your thoughts on how you would go about implementing this.

Thanks in advance for any guidance,

Ken.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小姐丶请自重 2024-11-16 03:40:47

也许您可以扩展缓存管理器并在现有检查之外提供布尔表达式。

您可以在控制器的 ThreadLocal 中设置该布尔值,以便每当调用服务时,该布尔值就位。

Perhaps you can extend the cache manager and provide a boolean expression in addition to the existing checks.

That boolean you can set in a ThreadLocal in your controller, so that whenever the service is invoked, the boolean is in place.

探春 2024-11-16 03:40:47

您可以创建一个刷新缓存的方法,并且仅当您需要来自数据库的值时才使用调试器运行它。

@Cacheable(modelId = "i18NTextCacheModel")
public List<I18NText> loadAll() {

    logger.debug("loadAll called");
    ...
}

@CacheFlush(modelId = "i18NTextFlushModel")
public Long save(I18NText entity) {

    logger.debug("save called");
    ...
}

You can create a method that flushes the cache and run it only with your debugger when you want a value from the DB.

@Cacheable(modelId = "i18NTextCacheModel")
public List<I18NText> loadAll() {

    logger.debug("loadAll called");
    ...
}

@CacheFlush(modelId = "i18NTextFlushModel")
public Long save(I18NText entity) {

    logger.debug("save called");
    ...
}
网名女生简单气质 2024-11-16 03:40:47

得到了与 @Bozho 建议类似的结果
如果请求参数 refresh-cache=true 被传递,缓存就会被绕过

我扩展了 DefaultRedisCacheWriter 并将其用作 CacheWriter

    RedisCacheManager cacheManager = RedisCacheManager
            .builder(new RefreshableRedisCacheWriter(redisConnectionFactory()))
            .cacheDefaults(cacheConfiguration)
            .build();

覆盖此 writer 中的 get() 方法

@Override
public byte[] get(String name, byte[] key) {

    Assert.notNull(name, "Name must not be null!");
    Assert.notNull(key, "Key must not be null!");

    HttpServletRequest request = ApiRequestContext.getRequestContext();
    if (Boolean.valueOf(request.getParameter("refresh-cache"))) {
        logger.info("bypassing cache for key: {}", key);
        return null;
    }

    return execute(name, connection -> connection.get(key));
}

ApiRequestContext 是一个自定义请求对象,此处存储在线程本地。
请注意,当此方法返回 null 时,将从数据库中获取该值并将其放回缓存中,从而有效地刷新缓存。

Arrived at a similar result as suggested by @Bozho
If the request parameter refresh-cache=true is passed, the cache gets bypassed

I extended DefaultRedisCacheWriter and used it as the CacheWriter

    RedisCacheManager cacheManager = RedisCacheManager
            .builder(new RefreshableRedisCacheWriter(redisConnectionFactory()))
            .cacheDefaults(cacheConfiguration)
            .build();

Overwrite the get() method in this writer

@Override
public byte[] get(String name, byte[] key) {

    Assert.notNull(name, "Name must not be null!");
    Assert.notNull(key, "Key must not be null!");

    HttpServletRequest request = ApiRequestContext.getRequestContext();
    if (Boolean.valueOf(request.getParameter("refresh-cache"))) {
        logger.info("bypassing cache for key: {}", key);
        return null;
    }

    return execute(name, connection -> connection.get(key));
}

ApiRequestContext is a custom request object here stored in the thread local.
Note that when this method returns null, the value is fetched from the db and put back into the cache, effectively refreshing the cache.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文