Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA background cache refresh

We have a high performance Java (J2SE) middleware app where latency is of utmost importance. It uses some standing data held in a legacy database, where a legacy application may occaisionally modify the data. Because of the latency requirement, we are planning to Cache the standing data, utilising JPA with Hibernate and maybe a cache provider such as Ehcache.

However, when the standing data is updated (by the legacy app) we need to be notified of this as soon as possible. I was thinking of setting an expiry on the cache, but then cache will not be refreshed until the next request for the data is made by the application - at which point the latency will be effected due to the database re-read.

Ideally we need the cache to return a stale value, and in the background the cache is updated/refreshed with the latest value from the database at regular intervals.

Is this possible with Ehcache? I have seen SelfPopulatingCache and CacheLoader, but this seems like I'm doing a lot of work (i'd have to hand write code for each entity). Also, does anyone have an example of a CacheLoader implementation? I was hoping for an async refresh option on the Query Cache.

Are there any other technologies out there that could provide a solution? We aren't bound by JPA provider or cache provider.

Could Spring @Cacheable provide a solution? I've seen spring ehcache cachable mentions self-populating-cache-scope, but its not clear to me what this means.

Thanks in advance.

like image 393
martin Avatar asked Apr 15 '11 08:04

martin


3 Answers

What database are you using?

EclipseLink 2.4 will provide a database event driven cache invalidation feature. This is integrated with Oracle database DCN/QCN. You may also be able to hook something up with triggers.

http://wiki.eclipse.org/EclipseLink/Examples/JPA/DCN

You may also wish to investigate Oracle GoldenGate, Coherence and TopLink Grid.

like image 100
James Avatar answered Nov 07 '22 03:11

James


If you can change the legacy application then one option is to send cache invalidation notices with something like ActiveMQ. If you can't change the legacy application another option is to add an indexed timestamp/rowversion column to your table and periodically poll it for changes since the previous poll.

like image 22
WhiteFang34 Avatar answered Nov 07 '22 03:11

WhiteFang34


I dont know how to do this using EhCache or other component, but a commom approach to this problem is to "have 2 caches". Let me explain: you have one cache serving your application with data (this cache will not have any update while serving application) and another cache beeing created by a timed worker with most recent data (you can create a cache every x seconds or every time you receive an event telling you that your data changed). When your new cache is complete you replace old cache with the new one, so your recently update cache is now serving application with 0 cache latency. As you can see, the problem with this approach is that you client may see stale data while your new cache is not complete. And, of course, it is a very expensive method (you will have 2 caches at memory very often and will build a new cache very often too).

like image 32
Plínio Pantaleão Avatar answered Nov 07 '22 01:11

Plínio Pantaleão