Search This Blog

Saturday 17 August 2013

How to cache ?

In the previous post we saw how to setup the cache provider for Hibernate. But that is not the end of the story. We need to decide what kind of concurrency we need. Does our data ever change? Can we live with stale data? All these factors are decided by the concurrency strategy we use. Hibernate provides us with four built in concurrency strategies (as of version 3.0):



Transactional
Read-write Nonstrict-read-writeRead-only
Where to use ?  Available only in a managed environment
such as a JTA environment
available only in
non- clustered environments


When to use ? Should be used for read-mostly data, but where stale data should never be read in the case of a rare updateShould be used for read-mostly data, but where stale data should never be read in the case of a rare update Use for read mostly data, where stale data is not such a big concern use only for data that never changes. E.g. data in a reference table.
How does it work ? It uses repeatable read isolation.( A read transaction blocks any writes (but not reads) while a write transaction blocks all.) It allows read committed transaction.(A read does not block any, but a write blocks all.) Hibernate uses a time-stamping mechanism to achieve the same. The data is flushed only on cache expiry. So stale data is a definite possibility here Simplest to use and is also an optimal strategy.

Based on the above summary the read-only cache is best suited for the BookType class. The hbm includes the cache configuration.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.object.cache">
    <class name="BookType" table="BOOK_TYPE_MASTER">
        <cache usage="read-only" /> <!-- These never change -->
        <id name="id" type="integer">
...
We have specified the type of concurrency strategy to apply for the BookType class. As BookType is reference data and never changes a read-only concurrency strategy has been applied.  
For every class/collection that we cache we need to define the physical cache region that will be used by the actual physical provider for the cache management.The value defaults to the class or collection role name.
In case of ehcache, this information is provided in a configuration file called ehcache.xml
<cache name="com.object.cache.BookType" maxElementsInMemory="5"
    timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" />
The element indicates that the com.object.cache.bookType cache region allows for a maximum of 5 cached objects held in memory, the number of seconds an object should remain the cache after it was last accessed ( 0 is like infinite), the number of seconds an object should remain in the cache after it was created (0 is again infinite) and if objects exceeding maxElementsInMemory should be allowed to be managed on  the disk.
This completes configuration of our second level cache for the BookType class.
I also added the settings for second level cache in the cfg file:
<property name="show_sql">true</property>    
<property name="use_sql_comments">true</property>    
<property name="format_sql">true</property>    

<!-- This is for testing purpose only -->
<property name="hibernate.generate_statistics">true</property>
        
<property name="hibernate.cache.use_structured_entries">true</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.provider_class">
    org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_query_cache">true</property>
The next step is to run and test the code.

No comments:

Post a Comment