Friday, August 15, 2008

Hibernate read-only cache strategy bug?

Hibernate has several cache stratagies, and one of them is ReadOnly. It looks like ReadOnly should be one which provides the best performance, which is also mentioned in Hibernate Reference. But just have a quick look at code of get method of that strategy:

public synchronized Object get(Object key, long timestamp) throws CacheException {
Object result = cache.get(key);
if ( result!=null && log.isDebugEnabled() )
log.debug("Cache hit: " + key);
return result;

That method is syncronized, which doesn't looks like good performance sign. Basicaly it is bottleneck specially for systems which require high-performance cache reading operations. I suppose, cache implementation itself has to take care about syncronisation stuff and stratgy shouldn't apply such strict restrictions. So it looks like obviouse bug.
Also, it blocks you from using of such feature like non-blocking loading if expired cache entries, which allows to serve the old content to subsequent threads until the cache entry has been updated.
NHibernate developers were also suprized with that syncronization and finaly have decided to remove it. See details here.
Regading to Java developers, as workaround, they can use NonstrictReadWriteCache strategy, which doesn't have syncronization and looks like suitable alternative for ReadOnly for the most cases.