[hibernate-dev] Query cache inefficiencies over longer Sessions

Galder Zamarreno galder at jboss.org
Mon Jan 18 08:18:16 EST 2010


Let's see if I can send this properly now to the list.

----- Forwarded Message -----
From: "Galder Zamarreno" <gzamarre at redhat.com>
To: "Steve Ebersole" <sebersol at redhat.com>
Cc: "Brian Stansberry" <bstansbe at redhat.com>, hibernate-dev at lists.jboss.org
Sent: Monday, January 18, 2010 1:52:54 PM GMT +01:00 Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna
Subject: Re: Query cache inefficiencies over longer Sessions

Had the wrong hibernate-dev list email on CC. Fixing it now.

----- Original Message -----
From: "Galder Zamarreno" <gzamarre at redhat.com>
To: "Steve Ebersole" <sebersol at redhat.com>
Cc: "Brian Stansberry" <bstansbe at redhat.com>, hibernate-dev at jboss.org
Sent: Monday, January 18, 2010 1:51:29 PM GMT +01:00 Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna
Subject: Query cache inefficiencies over longer Sessions

Hi Steve,

I'm looking into a post by Guenther (http://community.jboss.org/message/519752#519752) where he explains issues he's encountering with query cache. He's already entered two JIRAs before related to this:

http://opensource.atlassian.com/projects/hibernate/browse/HHH-4551
http://opensource.atlassian.com/projects/hibernate/browse/HHH-4577

He had initially complained about the lack of precision of nextTimestamp in JBC/Infinispan cache providers, but this precision deficiency is justified in a clustered environment, so we're not planning to change it for the time being. Looking at his last comment, it seems to me that his real problem is the fact that the timestamp query cache uses to store the queries, or to check whether a query is up to date comes from timestamp of when the session is created. The longer the sessions are, the least advantageous it is to use query cache in the current form.

Now, my question is, why not use Region.nextTimestamp() as timestamp when queries are to be cached rather than when the session was opened? This would most probably solve problems like the ones this user has because by the time a query and its resulset had been calculated, more than 100ms would have passed, assuming you don't use an in-memory database, which is what's recommended anyway.

Also, why not use Region.nextTimestamp() as timestamp when a query is actually executed when comparing with update timestamps rather than when session was opened?  

I'm not an authority on Hibernate code, but I suspect the reason why the decision was taken to use the timestamp when session is created might be because due to potential isolation problems between concurrent sessions updating query/entity caches on non-transactional cache providers. By using the timestamp when session was opened, you guarantee that queries will be invalid from the moment that you started that session, hence any partial updates that might have happened to caches between session open and query execution won't be used by other sessions.

I don't think this would be a problem with transactional cache providers though, i.e. infinispan/jbc. The fact that updates happen on commit time and transaction isolation would protect from such situations.

I think it might be worth adding some configuration option that allows for more precision for query caches used with transactional cache providers. Such option could force Region.nextTimestamp() to be used to mark when queries are executed, and when these are updated, rather when session was opened.

Thoughts?

Galder



More information about the hibernate-dev mailing list