Oct 08

In production you may have run into problems where a certain flow is slow, turning hibernate statistics on using the jmx-console would be a good idea, but debugging what actually corresponds to this slow flow could be like searching for a needle in this haystack. The obvious thing would be to organize the data in such a way that all queries for a flow along with their time are presented together. The blog discusses one approach for doing so assuming we are using spring and hibernate.

In our case we were interested in the hql, sql and time taken for them. We were also running into some issues with the session size, so had a piece to capture that too. The whole approach is based on these simple steps:

  1. Putting in a flow identifier
  2. Inject our own SessionStatsCollector
  3. Wire it via JMX
  4. Get callbacks for the original sql

Flow identifier
The utility of this approach depends on how easily can we pin point each flow. The url along with the thread id is a good starting point. However if the urls are kind of the same and the request parameters have a special token, we can use that as our flow discriminators. This token is injected into the NDC for the later part of the tool to pick it up and arrange diagnostic information.

Inject SessionStatsCollector
Hibernate does not allow any hook points to the session stats collector, so to get our custom stats collector in, we used a simple cglib proxy for it. The proxy intercepts only queryExecuted and closeSession methods. While queryExecuted is used to capture the hql, time and number of rows, closeSession callbacks helps us log all the collected information together.

Wire it via JMX
Since the original mbean does not support logging flows, the new jmx bean exposes one method profileFlows which takes the flow pattern and a boolean to indicate if the session size should be logged. Determining the session size is a heavy operation, so on most cases we may not want to do so. There is another method to reset the bean which would revert to the original statistics collector from our souped up version.

Sql callbacks
We were interacting with our dba group, for whom the hql was like greek, so the original sql was important to us, since the original stats implementer does not get any callbacks for this, we injected our own entity interceptor which gives a callback to the stats collector for the sql.

So in short with about 8 classes, we can create something which gives us some indicators of the flow performances. The performance and memory overhead introduced by this is nominal and can be turned off at any point.

The classes for this are easy to code, if laziness gets in your way, post a comment and will upload it.

Tagged with:
Apr 15

An object by itself is intensely uninteresting.Objects contribute to the behavior of a system by collaborating with one another.One of relationship aspects between Objects can be represented by Association.

When we bring in Cardinality in Association we get One-to-One, One-to-Many and Many-to-Many.In later two One-to-Many and Many-to-Many we use Collection to represent many Side.For example: An Order have many OrderDetail’s.

We have these associations represented in Relational DBMS using foreign keys.So from any O-R framework we expect that to take care of these associations in smartest way possible.As these can easily become a performance bottle neck for the application.Some time you may end up loading lot of Data into memory, and sad part is you are never going to use them.  Continue reading »

Tagged with:
May 05

In this blog, I take a look at the query cache, well it is more than a cursory glance, would try to dive in some detail. The blog would explain some of the details of it (enough introduction, lets get to the meat).

As most of us already know, hibernate supports plugging in external cache providers for addressing certain aspects of performance. There are some very good articles on hibernate caching, some of which are
Understanding the second level and query cache
Chapter 19: Improving performance

Lets start with what we are trying to achieve by query cache. The intention is to cache the results against the query (the sql along with the parameters and their values). The effectiveness of the cache is determined to a large extent by its invalidation logic. The isolation level semantics that we want the cache to follow also impacts this logic. In this blog I will go over some of the these details and how it impacts some of the performance choices I need to make. Rather than detail the implementation logic, will run over some common scenarios explaining the implementation detail along the way. Continue reading »

Tagged with:
Apr 07

Persistence in enterprise solutions is not only about CRUD operations, but handling concurrency. Concurrency is handled mostly by locks at the database levels. These locks are configured at the dataobject level and cannot be easily controlled from the flow. The only way of controlling it based on the flow is a programmatic approach to it (via JPA locking api or equivalents). Most of the concurrency issues are discovered only in the later stages of development or at times only after the application goes live, a code change at these points is very difficult. Continue reading »

Tagged with:
preload preload preload