Sunday, 6 May 2012

Hibernate Caching - Part I - Introduction

I found a plenty of blog posts about Hibernate cache solutions, but most of them don't take care of the concurrency strategies. In the following posts I'll try to give a deeper look into Hibernate caching and concurrency strategies.

Hibernate Caching - Introduction

To improve the performance the hibernate gives you a couple of caching option. With well configured hibernate caching we can improve the performance of our application because we can significantly reduce the database hits. Hibernate operates with 3 caches, in the followings I'll have a quick look at them.
1. First level cache - also known as Session(EntityManager) cache.

Hibernate provides and automatically handles it. The first level cache contains all the entities which have been pulled out during the session. The entities stored as real objects (with their references). And if one entity is retrieved twice, the same object (reference value) will be returned.

There are a couple of methods with which we can control the first level cache, but usually it's not an issue. Eg.: detach, clean, etc.

Comment: You have to be careful because nothing thread safe in a entity manager, neither the entities nor the session, but obviously you can make the synchronization.

2. Second level cache

A cache level under the session cache. This cache relates to the SessionFactory (EntityManagerFactory) and all the sessions can use the stored values. Hence a multiple Session can reach the same entity stored here, the second level cache doesn't store entity instances, therefore they won't be shared between different sessions. The 2nd level cache stores only (called) dehydrated entities. The dehydrated entity consist of values of the fields in the entity but it does not obtain a reference to an instance.

To use the 2nd level cache well, we have to know the cache concurrency strategies.

Read-only
A read-only cache is good for data that needs to be read often but not modified. It is simple, performs well, and is safe to use in a clustered environment.
NonStrict Read-write
Some applications only rarely need to modify data. This is the case if two transactions are unlikely to try to update the same item simultaneously. In this case, you do not need strict transaction isolation, and a nonstrict-read-write cache might be appropriate. If the cache is used in a JTA environment, you must specify hibernate.transaction.manager_lookup_class. In other environments, ensore that the transaction is complete before you call Session.close() or Session.disconnect().
Read-write
A read-write cache is appropriate for an application which needs to update data regularly. Do not use a read-write strategy if you need serializable transaction isolation. In a JTA environment, specify a strategy for obtaining the JTA TransactionManager by setting the property hibernate.transaction.manager_lookup_class. In non-JTA environments, be sure the transaction is complete before you call Session.close() or Session.disconnect().
Transcational
The transactional cache strategy provides support for transactional cache providers such as JBoss TreeCache. You can only use such a cache in a JTA environment, and you must first specify hibernate.transaction.manager_lookup_class.
Fortunately the names are very descriptive but it worth to understand the real behavior in Part 2 link.
3. Query cache
The responsibility of this is to store the query string and the ids (primary keys) of the result. This cache stores queries as a real SQL statements, replaced the parameters with the real values. The query cache doesn't store anything about the entities apart from the list of their ids.

Links

Presentation

I've created a presentation about this topic. Feel free to use is.

Hibernate caching
View more PowerPoint from bsudy

Code

You can check out or download the code of the test from Github repository: https://github.com/bsudy/hibernatecache

No comments:

Post a Comment