-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 
Author Message
 Post subject: How to evict second level cache in a transactional context?
PostPosted: Thu Mar 01, 2012 9:45 am 
Newbie

Joined: Thu Mar 01, 2012 5:10 am
Posts: 7
Hi,

we're using Hibernate 3.6 with Ehcache 2.5 (and Bitronix 2.1.1, if this matters).

A number of entities and queries are configured to be cached by 2nd level cache. This works well so far.
However there are sometimes changes to the database by other processes so we need to evict the cache explicitly. We created a servlet for that purpose and call the various eviction methods:
Code:
    Cache cache = HibernateUtil.getSessionFactory().getCache();
    cache.evictDefaultQueryRegion();
    cache.evictQueryRegions();
    cache.evictQueryRegion(UpdateTimestampsCache.REGION_NAME);
    cache.evictEntityRegions();
    cache.evictCollectionRegions();


This clears the cache indeed, but we noticed that this seems to cause the application not work properly anymore, and after some time we get the following in the log:

Code:
org.hibernate.event.def.DefaultLoadEventListener - Error performing load command
org.hibernate.cache.CacheException: net.sf.ehcache.transaction.TransactionTimeoutException: transaction timed out
      at net.sf.ehcache.hibernate.strategy.TransactionalEhcacheEntityRegionAccessStrategy.get(TransactionalEhcacheEntityRegionAccessStrategy.java:71)
      at net.sf.ehcache.hibernate.nonstop.NonstopAwareEntityRegionAccessStrategy.get(NonstopAwareEntityRegionAccessStrategy.java:122)
      at org.hibernate.event.def.DefaultLoadEventListener.loadFromSecondLevelCache(DefaultLoadEventListener.java:587)
      at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:459)
      at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227)
      at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:285)
...


The Javadoc for org.hibernate.Cache clearly states this:
Quote:
CAUTION: None of these methods respect any isolation or transactional semantics associated with the underlying caches. Specifically, evictions perform an immediate "hard" removal outside any transactions and/or locking scheme(s).


I suppose it's not a good idea to clear the cache this way in our transactional context - but how can you do it right?

Thanks,
Gunnar


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Thu Mar 01, 2012 11:02 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Hi Gunnar,

it looks to me that the TransactionTimeoutException has actually nothing to do with the evictions you made previously.
it looks to me rhater that you specified, somewhere

Quote:
Transaction tx = ...

tx.setTimeout(numseconds)


or on some other place you configured a TransactionTimeout (either on your BitronixTransactionManager or EHcache directly).
While your Transaction timed out you still were working with it, so the exception raised.
That's what I think what was happening.

N.B.: Where did you found documentation about using Ehcache as transactional 2L-Cache in hibernate?
According official hibernate documentation (Hibernate4) Ehcache still isn't useable as transactional 2L-Cache implementation.


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Thu Mar 01, 2012 11:23 am 
Newbie

Joined: Thu Mar 01, 2012 5:10 am
Posts: 7
Hi!

pb00067 wrote:
or on some other place you configured a TransactionTimeout (either on your BitronixTransactionManager or EHcache directly).


Well, there is a default timeout value configured (bitronix.tm.timer.defaultTransactionTimeout=300) and this is about the time it took to show up this exception. But this *only* happens if I call the eviction before. So it seems that this eviction somehow causes a lock or something.

pb00067 wrote:
N.B.: Where did you found documentation about using Ehcache as transactional 2L-Cache in hibernate?
According official hibernate documentation (Hibernate4) Ehcache still isn't useable as transactional 2L-Cache implementation.


It says so here: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/performance.html#performance-cache-transactional and here: http://ehcache.org/documentation/apis/jta#faq


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Thu Mar 01, 2012 11:40 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Quote:
According official hibernate documentation (Hibernate4) Ehcache still isn't useable as transactional 2L-Cache implementation.


Seems that I looked into an older Hibernate-version-documentation while I was believing to see documentation of Hiberant4 ;-)


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Thu Mar 01, 2012 11:54 am 
Newbie

Joined: Thu Mar 01, 2012 5:10 am
Posts: 7
Official Hibernate documentation seems not to be very well maintained in this regard. E. g. Infinispan isn't mentioned at all, although it's supposed to be the official successor to JBoss Cache.

Btw: we tried Infinispan in the beginning, but had other issues with that, so switched to Ehcache.


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Thu Mar 01, 2012 1:27 pm 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Quote:
Btw: we tried Infinispan in the beginning, but had other issues with that, so switched to Ehcache.


When I was comparing between Infinispan and EHcache, the latter did not yet support transactional strategy yet.
Finally I too opted for EHcache, because I trusted it more (at that time Infinispan was very new).

I'm still using EHcache with read-write strategy:
so I am not forced to use any TransactionManager at all,
and evictions are never causing problems to me.


Last edited by pb00067 on Fri Mar 02, 2012 3:14 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Thu Mar 01, 2012 3:07 pm 
Newbie

Joined: Thu Mar 01, 2012 5:10 am
Posts: 7
We thought about this (avoiding transactional strategy), too, but as we understand it you have to do it this way if you want to keep the cache in sync with the database. Or did I completely misunderstand this?

But thinking again about this... in which case is read/write sufficient and when do I really need transactional?


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Thu Mar 01, 2012 6:55 pm 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Hi Gunnar,

also with read/write your are able to keep the cache in sync with the database.
In our company we use now EHCache with read/write since more than a year,
and we never experienced stale data in 2L-Cache.

Quote:
when do I really need transactional?


The unique difference I saw between using transactional Infinispan and read/write EHCache is following:

Transactional:
Once a entity object was cached, it never was reread from database again,
also when performing updates on that object, followed either by commits or rollbacks:
the 2Lcache always had the correct (up-todate) object cached.

Non Transactional (read/write):
In this configuration in contrast to Transactional the 2L-cache is usually not able to maintain multiple versions (=states) of the same entity object, thus when you modify an object and flush, the regarding object (update to the new values) in 2L-Cache get locked until your transaction ends. While this Lock this entity in 2L-Cache is not accessible to other concurrent transactions (otherwise it would violate isolation levels), so on demand they will re-read that object from database again.
Similiar thing happens when you finally rollback your transaction instead to commit it:
The 2L-cache don't has a copy of your entity object in original state, so it is not able to turn back to it's original state: the entry gets discarded.
So on next demand, that entity object must be read again from database, (after this, it will be reput into 2LCache again).


Conclusion:
Transactional 2L-cache is better for high-concurrency access,
that means when concurrent threads are very often accessing and updating the same entity objects.

If indeed updates are not so often and if it not represents a problem to you,
that sometimes an object is even reread from database again,
then also non Transactional 2L-cache should work well to you.


Last edited by pb00067 on Fri Mar 02, 2012 4:19 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Fri Mar 02, 2012 3:25 am 
Newbie

Joined: Thu Mar 01, 2012 5:10 am
Posts: 7
Thank you very much!
I'll discuss this with my colleague, and we'll probably give it a try with read/write.


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Fri Mar 02, 2012 4:59 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Hi Gunnar,

can you also report the stacktrace of the net.sf.ehcache.transaction.TransactionTimeoutException ?
(or the full stacktrace of org.hibernate.cache.CacheException).
Maybe from this stacktrace we can see if there effectively were locks being held.


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Fri Mar 02, 2012 5:45 am 
Newbie

Joined: Thu Mar 01, 2012 5:10 am
Posts: 7
Actually it turned out that a bug in ehcache 2.5.0 was causing a deadlock. It has been fixed in 2.5.1 and after updating the lib our problem has disappeared. :-)

In case you're interested, it was this one: https://jira.terracotta.org/jira/browse/EHC-903

But nevertheless thanks again for your help!


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Fri Mar 02, 2012 6:14 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Just one more question for curiousness:

Are you using Bitronix with the The Last Resource Commit optimization feature (allowing you to acceed your database as non XA-Datasource),
or do you access your database with XA protocol (2 Phase-commits) ?


Top
 Profile  
 
 Post subject: Re: How to evict second level cache in a transactional context?
PostPosted: Fri Mar 02, 2012 8:52 am 
Newbie

Joined: Thu Mar 01, 2012 5:10 am
Posts: 7
pb00067 wrote:
Are you using Bitronix with the The Last Resource Commit optimization feature (allowing you to acceed your database as non XA-Datasource),
or do you access your database with XA protocol (2 Phase-commits) ?


We use a "real" XA datasource (oracle.jdbc.xa.client.OracleXADataSource).


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.