Guava Cache, how to block access while doing removal

只愿长相守 提交于 2019-11-28 13:02:59

You stated Guava Cache, but there is no code example, so I give a general answer.

For the below I assume that you have a "loading cache" aka "self populating cache" schema.

Solution 1: Properly design your cache interactions and database transactions.

The update process invalidates the cache entry, as soon a transaction is started on it.

  begin transaction
  touch some of the entry data with SQL UPDATE to have it in the transaction
  remove the entry from the cache
  ....
  now you can do more operations on the database regarding the entry data
  if you have the proper isolation level, reads from the database will stall
  until the transaction is committed
  ....
  end transaction

If you remove the entry from the cache and then start the transaction you introduce a race condition.

Solution 2: Use caches that block out concurrent operations on the same key/entry.

Take a look on ehcache Blocking Cache. Or take a look on cache2k where the blocking behaviour is the default.

But, however, you need to do additional locking on the loader level by yourself. E.g. like the example below.

Solution 3: Do the locking by yourself on top of the cache and wrap all cache operations. E.g. with something like:

 Cache cache;
 Lock[] locks = new Lock[16];
 { /* initialize locks */ }

 public Object get(Object key) {
   int idx = key.hashCode() % locks.length;
   locks[idx].lock();
   try { return cache.get(key); 
   } finally { locks[idx].unlock(); }
 }

 public void update(Object key, Object obj) {
   int idx = key.hashCode() % locks.length;
   locks[idx].lock();
   try { return cache.put(key, obj); 
   } finally { locks[idx].unlock(); }
 }

You can also look at the BlockingCache implementation from ehcache and take some inspiration from there.

Have fun!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!