Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Spring @Cacheable block if accessed by more that 1 thread?

If a method marked @Cacheable takes 10 minutes to complete and two threads t1,t2 access the method.

t1 accesses at time 0 (cache method is now run for first time) t2 accesses at time t1+5mins

Does this mean that t2 will not access the data for approx 5 mins since t1 has already started the @Cacheable operation and it's due to complete in 5 mins(as its been running for 5 mins) or will a new call to @Cacheable be invoked by t2?

like image 243
blue-sky Avatar asked Nov 12 '14 17:11

blue-sky


4 Answers

Since Spring 4.3, you can get the desired blocking behavior by adding the sync = true flag:

@Cacheable(value="cacheName", key="{#keyField1, #keyField2}", sync = true)
like image 121
JayVeeInCorp Avatar answered Sep 25 '22 18:09

JayVeeInCorp


If the result of the first execution hasn't been cached, the second invocation will proceed.

You should understand that @Cacheable is centered around the content of the cache (and not specifically a thread's execution context [well, kind of; the cache still needs to be threadsafe]). On execution of a method, the cache is first checked to see if the key exists: if t1 is taking a while to complete, its result will not be cached therefore, concurrent executions will proceed without regard for t1's execution

like image 20
kolossus Avatar answered Sep 23 '22 18:09

kolossus


There is no blocking on @Cacheable.

But you can use blocking cache strategy in cache implementation. First query found miss has the responsibility to rebuild the cache. Others queries wait until the cache is rebuilt.

  • For local cache implementation, use ReadWriteLock. See the net.sf.ehcache.constructs.blocking.BlockingCache.
  • For remote cache implementation, use ghetto central lock.
like image 23
Loki Avatar answered Sep 25 '22 18:09

Loki


As colossus explained, the cache is checked prior to the method call. So, if the item is not in cache (as will be the case at t1 + 5 mins), the method invocation will happen for thread t2 as well.

There is no "blocking" on the @Cacheable annotation. t2 will call the method as if there was a cache-miss and hence t2 will also take 10 minutes to complete the same method.

like image 34
Jigish Avatar answered Sep 22 '22 18:09

Jigish