简体   繁体   中英

Bypassing the @Cacheable annotation in Production for debugging

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", eg 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.

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.

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.

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");
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM