Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update cache every 30 minutes in spring?

I have following declaration:

@Cacheable("books")
public Book findBook(ISBN isbn) {...}

But I want to update the cache every 30 minutes. I understand that I can create @Scheduled job to invoke method annotated @CacheEvict("books")

Also, I suppose that in this case all books will be cleared but it is more desirable to update only stale data(which were put in cache > 30 minutes ago)

Is there anything in spring that can facilitate implementation?

like image 914
gstackoverflow Avatar asked Sep 11 '19 10:09

gstackoverflow


People also ask

How do I refresh Redis spring boot cache?

All you have to do is create class called e.g. CacheService and create method that will evict all cached objects you have. Then you annotate that method @Scheduled and put your interval rate. Save this answer.

How do I evict multiple caches in spring?

Spring provides two ways to evict a cache, either by using the @CacheEvict annotation on a method, or by auto-wiring the CacheManger and clearing it by calling the clear() method.


1 Answers

Cache implementations provide a feature named expire after write or time to life for this task. The different cache implementations have a lot variances. In Spring no effort was made to try to abstract or generalize the configuration part as well. Here is an example of programmatic configuration for your cache in Spring, if you like to use cache2k:

@Configuration
@EnableCaching
public class CachingConfig extends CachingConfigurerSupport  {

  @Bean
  public CacheManager cacheManager() {
    return new SpringCache2kCacheManager()
      .addCaches(
        b->b.name("books").keyType(ISBN.class).valueType(Book.class)
            .expireAfterWrite(30, TimeUnit.MINUTES)
            .entryCapacity(5000);
  }
}

More information about this is in cache2k User Guide - Spring Framework Support. Other cache implementations like, EHCache or Caffeine support expiry as well, but the configuration is different.

If you like to configure the cache expiry in a "vendor neutral" way, you can use a cache implementation that support the JCache/JSR107 standard. The standard includes setting an expiry. A way to do it, looks like this:

@Configuration
@EnableCaching
public class CacheConfiguration {

  @Bean
  public JCacheCacheManager cacheManager() {
    return new JCacheCacheManager() {
      @Override
      protected Collection<Cache> loadCaches() {
        Collection<Cache> caches = new ArrayList<>();
        caches.add(new JCacheCache(
          getCacheManager().createCache("books",
          new MutableConfiguration<ISBN,Book>()
            .setExpiryPolicyFactory(ModifiedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 30)))),
          false));
        return caches;
      }
    };
  }
}

The in JCache is, that there are configuration options, that you need, which are not part of the standard. One example is limiting the cache size. For this, you always need to add a vendor specific configuration. In case of cache2k (I am the author of cache2k), which supports JCache, the configurations are merged, which is described in detail at cache2k User Guide - JCache. This means on a programmatic level you do the "logic" part of the configuration, where as, the "operational" part like the cache size is configurable in an external configuration file.

Unfortunately, its not part of the standard how a vendor configuration and a programmatic configuration via the JCache API needs to interoperate. So, even a 100% JCache compatible cache might refuse operation, and require that you only use one way of configuration.

like image 183
cruftex Avatar answered Sep 28 '22 00:09

cruftex