Peter Bean
Peter Bean

Reputation: 333

Spring Cache with Redis - How to gracefully handle or even skip Caching in case of Connection Failure to Redis

I've enabled Caching in my Spring app and I use Redis to serve the purpose. However, whenever a connection failure occurs, the app stops working whereas I think it had better skip the Caching and go on with normal execution flow.

So, does anyone have any idea on how to gracefully do it in Spring ?

Here is the exception I got.

Caused by: org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool

Upvotes: 17

Views: 11971

Answers (3)

Yashasvi Raj Pant
Yashasvi Raj Pant

Reputation: 1424

You can use CacheErrorHandler as suggested by Stephane Nicoll. But you should make sure to make RedisCacheManager transactionAware to false in your Redis Cache Config(to make sure the transaction is committed early when executing the caching part and the error is caught by CacheErrorHandler and don't wait until the end of the execution which skips CacheErrorHandler part). The function to set transactionAware to false looks like this:

    @Bean
    public RedisCacheManager redisCacheManager(LettuceConnectionFactory lettuceConnectionFactory) {
        JdkSerializationRedisSerializer redisSerializer = new JdkSerializationRedisSerializer(getClass().getClassLoader());

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(redisDataTTL))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer));

        redisCacheConfiguration.usePrefix();

        RedisCacheManager redisCacheManager = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
                .cacheDefaults(redisCacheConfiguration)
                .build();

        redisCacheManager.setTransactionAware(false);
        return redisCacheManager;
    }

Upvotes: 3

Ashish Goel
Ashish Goel

Reputation: 39

Similar to what Stephane has mentioned, I have done in by consuming the error in try catch block. Adding a fall back mechanism where if Redis is not up or may be the data is not present then I fetch the data from DB.(Later if I find one then I add the same data in Redis,if it is up to maintain consistency.)

Upvotes: -1

Stephane Nicoll
Stephane Nicoll

Reputation: 33091

As from Spring Framework 4.1, there is a CacheErrorHandler that you can implement to handle such exceptions. Refer to the javadoc for more details.

You can register it by having your @Configuration class extends CachingConfigurerSupport (see errorHandler()).

Upvotes: 8

Related Questions