Tuesday, 18 December 2012

Transactional patterns (and anti-patterns)

1. Session-per-operation anti-pattern
2. Session-per-request pattern
3. Conversations
4. Session-per-application


1. Session-per-operation anti-pattern

This is an anti-pattern of opening and closing a Session for each database call in a single thread.

2. Session-per-request pattern

This is the most common transaction pattern.The term request here relates to the concept of a system that reacts to a series of requests from a client/user.
At the beginning of handling such a request, the application opens a Hibernate Session, starts a transaction, performs all data related work, ends the transaction and closes the Session.
Within this pattern there is a common technique of defining a current session to simplify the need of passing this Session around to all the application components that may need access to it.
 Hibernate provides support for this technique through the getCurrentSession method of the SessionFactory.
The concept of a "current" session has to have a scope that defines the bounds in which the notion of "current" is valid. This is purpose of the org.hibernate.context.spi.CurrentSessionContext contract. There are 2 reliable defining scopes:

  • First is a JTA transaction because it allows a callback hook to know when it is ending which gives Hibernate a chance to close the Session and clean up.Using this implementation, a Session will be opened the first time getCurrentSession is called within that transaction.
  • Secondly is this application request cycle itself.Here an external component is responsible for managing the lifecycle and scoping of a "current" session. At the start of such a scope, ManagedSessionContext's bind method is called passing in the Session. At the end, its unbind method is called. Some common examples of such "external components" include:
    • javax.servlet.Filter implementation
    • AOP interceptor with a pointcut on the service methods
    • A proxy/interception container

The getCurrentSession() method has one downside in a JTA environment. If you use it, after_statement connection release mode is also used by default. Due to a limitation of the JTA specification, Hibernate cannot automatically clean up any unclosed ScrollableResults or Iterator instances returned by scroll() or iterate(). Release the underlying database cursor by calling ScrollableResults.close() or Hibernate.close(Iterator) explicitly from a finally block.

3. Conversations

The session-per-request pattern is not the only valid way of designing units of work. Many business processes require a whole series of interactions with the user that are interleaved with database accesses. In web and enterprise applications, it is not acceptable for a database transaction to span a user interaction.
Even though we have multiple databases access here, from the point of view of the user, this series of steps represents a single unit of work. There are many ways to implement this in your application.

A first naive implementation might keep the Session and database transaction open while the user is editing, using database-level locks to prevent other users from modifying the same data and to guarantee isolation and atomicity. This is an anti-pattern, because lock contention is a bottleneck which will prevent scalability in the future.

4. Session-per-application

Discussion coming soon..

http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch02.html#session-per-request

No comments:

Post a Comment