I would like to create an application, where I would use Hibernate L2 Cache to reduce the unnecessity to always requesting database for data.
In my application, over 80% of the time would be READ operation, and less than 20% would be Create / Update / Delete Operation. Therefore I think using Hibernate L2 Cache would be beneficial. However, as we are going to horizontal scale the application, we would like to use Infinispan as the L2 Cache of Hibernate.
However there are several questions which we are uncertain of.
If I understand correctly, Hibernate L2 Cache should work by updating the cache, whenever there is a new create / update / delete operation, or when the query has not yet queried previously. Therefore on a multiple servers setup connecting to the same database, since there are network IO issue, how could multiple update operation works in such environment? As the 2 application server may update the database simultaneously, each update the same entity to different data, but due to network IO issue, how could Hibernate know this data should be cached and synced, and this data should not?
It depends what kind of cache you are using. An invalidation cache, which I would suggest you to use here, will just invalidate cache entries that are stale. A replicating cache would replicate the changes to each node in the cluster. Hibernate just asks the cache implementation for the cache entry and if the cache returns that, it will use that and avoid accessing the database. If the cache entry is stale or how much blocking is involved in that cache lookup depends on the transaction configuration of the cache.
Related
Does Ehcache replicate the underlying Disk Store to other nodes, when replication enabled ?
And when element is searched in cache, which is overflown to disk, does cache search disk for that element or it returns NULL ?
Ehcache 2.x replication is based of cache event listeners and so happens irrelevant of the tiering configured. That means that any mutation on the cache once it has been configured will be replicated. This also means that if you were to configure it on a cache already having content on disk, that would not get replicated (Note: this change may be considered invalid and cause the cache to drop disk content - I did not test it).
When you Cache.get from a multiple tier cache, all tiers, from faster to slower, will be accessed to find the entry and will stop as soon as found.
Note also that since Ehcache 2.6.x overflow is no longer the storage model. All entries will exist in the disk tier while hot entries will also leave on heap. See another answer for more details.
I have two context on single tomcat pointing to same database. I am using ehcache for 2nd level caching with Hibernate.
Now, when I do any create/update/delete operation on database, it reflect in contect1 cache but to update in contecxt2 cache, it took almost 15-20 min. I can't use refresh/clear function in context2 as I don't know when to refresh.
How Can I refresh context2's Hibernate cache when there is any update happened through context1?
Also to do clustering for Hibernate cache, I need to give IP address and port number, but in my case, both are same for two contexts. So I think I can't use Hibernate cache clustering.
I have an application where I get the data from database (using hibernate).
I want to load the cache (per user) with database state once per day and use the cache instead.
I'm using Spring framework with Hibernate and I know that both of them have some caching possibilities.
What are the differences between them? What would be a better choice?
Starting with Hibernate cache is a more prudent decision in my view, especially because the two don't exclude each other. In terms of performance Spring cache can offer you more, its much higher in the stack, you can cache business results (basically more than you can with hibernate's second level cache).
However one outstanding distinction is clearing the cache. With Spring cache you need to clear explicitly, while the hibernate cache is maintained automatically if your inserts, updates and deletions go through hibernate's framework.
In the context of the projects that I'm involved, using hibernate's second level cache is assumed, a default almost. Spring cache we use for the data that are much more static in nature.
Hibernate has 2 levels of cache. 1. First level 2. Second level
Second level chache is for the whole application and first level cache is for the current hibernate session. There is no cache available per user basis.
Also if you are using spring managed beans + caching. There is a provision for you to cache the beans for entire application rather than for a user. (little uncertain on this)
It sounds to me that you want to store the data in the user's session. ie., as long as the user is having an active session. Spring has a session scoped beans you may want to use these to cache the data per user.
Scenario: Project consists of reference data which is updated once a week. Hence constantly querying this reference data for every transaction from the database is not efficient. Hence the motivation to cache this data.
Question: If secondary level caching and query caching in Hibernate is activated and the cache element in the hibernate configuration is set to read-only, how will hibernate know when to update the cache if a change is made to the database via another program. Is this automatically handled by Hibernate or do we have to clear the cache using some trigger?
If this is handled by Hibernate could someone shed light on how this is handled?
The JBoss documentation was not very clear about the management of the cache.
I am currently using Hibernate 3.6 with Spring 3.1 and do not wish to upgrade to Hibernate 4 if its not necessary.
It wont.
The second level cache expects all access to the data to happen via the ORM framework so if you have another actor in the db your cache will become stale.
You can clear the cache though - see this
code snippet
So you could expose a service that allows the 3rd party to clear the cache on your app when the database gets updated.
I have a scenario where the unit of work is defined as:
Update table T1 in database server S1
Update table T2 in database server S2
And I want the above unit of work to happen either completely or none at all (as the case with any database transaction). How can I do this? I searched extensively and found this post close to what I am expecting but this seems to be very specific to Hibernate.
I am using Spring, iBatis and Tomcat (6.x) as the container.
It really depends on how robust a solution you need. The minimal level of reliability on such a thing is XA transactions. To use that, you need a database and JDBC driver that supports it for starters, then you could configure Spring to use it (here is an outline).
If XA isn't robust enough for you (XA has failure scenarios, such as if something goes wrong in the second phase of commits, such as a hardware failure) then what you really need to do is put all the data in one database and then have a separate process propagate it. So the data may be inconsistent, but it is recoverable.
Edit: What I mean is that put the whole of the data into one database. Either the first database, or a different database for this purpose. This database would essentially become a queue from which the final data view is fed. The write to that database (assuming a decent database product) will be complete, or fail completely. Then, a separate thread would poll that database and distribute any missing data to the other databases. So if the process should fail, when that thread starts up again it will continue the distribution process. The data may not exist in every place you want it to right away, but nothing would get lost.
You want a distributed transaction manager. I like using Atomikos which can be run within a JVM.