Spring cachable not synchronized

I have a singleton class (@Service annotation). This class has a method that requires 200/300 ms to execute.

This method is annotated using @Cacheable and synchronized.

@Cacheable(value="nextPlaying", key = "#startingFrom.getYear() + #startingFrom.getMonth() + #startingFrom.getDay() + #startingFrom.getHours() + #startingFrom.getMinutes() + #locale.getLanguage()") public synchronized List<Match> getNextPlaying(Date startingFrom, Locale locale) 

Having started several threads calling this method, I see that for these 200/300 ms, until the result is cached, it starts the method again and again before caching. It seems that the @Cacheable annotation does not account for synchronization ... Is this a bug?

+5
source share
2 answers

When you use the @Cacheable annotation, the code that implements the cache search is outside your method. Therefore, a synchronized modifier does not affect it.

If you want all streams to use the caching result, you must create a synchronized method that transfers the call to the getNextPlaying caching method. Something like that:

 public synchronized List<Match> getNextPlayingSynchronized(Date startingFrom, Locale locale){ return getNextPlaying(Date startingFrom, Locale locale); } ... @Cacheable(value="nextPlaying", key = "#startingFrom.getYear() + #startingFrom.getMonth() + #startingFrom.getDay() + #startingFrom.getHours() + #startingFrom.getMinutes() + #locale.getLanguage()") public List<Match> getNextPlaying(Date startingFrom, Locale locale){ ...//your old method without the synchronized modifier } 

It is important that these methods are in different classes. Otherwise, the aspects do not work.

+10
source

The good news is, spring framework 4.3 provided you with a way to support your need by adding sync = true to @Cacheable.

+14
source

Source: https://habr.com/ru/post/1214755/


All Articles