i want to use ehcache not only as a cache but as a container of dirty objects that i want to flush to my database when the objects get evicted/expired. during normal processing, i use a key to lookup in ehcache. if key is not present, i read data from database and put it in ehcache. the value is actually a complex object that i modify. when the ttl/idle time/overflow condition happens, i see that CacheEventListener callbacks get invoked. but there is a big problem. the notifyElementExpired is called after the key-value are removed from cache. so there is a race condition. if i do the task of flushing the dirty value to cache in notifyElementExpired and at the same time, in another thread, read for the same key happens, then there is a synchronization issue. the 2nd thread will not find the object in ehcache, and hence will go to database while the other thread is still getting ready to flush.
i tried experimenting with write-through ehcache and i dont think thats also working.
is there a solution here??
i would really appreciate good solutions to this problem even if it involves some other caching mechanism other than ehcache.
thanks
If you're ok with a purely in-memory cache, I'd suggest extending the Google Guava library's CacheLoader, ex:
public class DBLoader extends CacheLoader<String, String> {
@Override
public String load(String key) throws Exception {
// load a value from the database
return value;
}
}
Then in usage, something like:
private LoadingCache<String, String> dbCache = CacheBuilder.newBuilder()
.expireAfterWrite(CACHE_EXPIRE_IN_SECONDS, TimeUnit.SECONDS)
.build(new DBLoader());
String value = dbCache.get(someKey);
You'll need to tidy that up with proper exception handling of course.
I find guava to be much more straightforward than getting ehcache configured properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With