Tuesday, 16 April 2013

Ambient Session and Transaction Management with TinyNH, the Simple NHibernate Infrastructure

So far, you've:

- Created your domain model entity classes
- Added a ConfigurationBuilder to initialise your NHibernate Configuration and class mappings
- Added a ConfigurationStore as an application-wide point of access for your Configuration and ISessionFactory
- Maybe added some automated database tests

It’s time to start writing some code to load and save our objects!

When working with NHibernate, the central point for accessing your objects is the NHibernate ISession. You can load individual objects using the Get method, query using a range of mechanisms and save new / modified objects to the database. The session really is where it all happens.

It is also a good practice to execute your work in the scope of a transaction. This applies even when you aren't saving any changes to your data. A transaction is an important consistency boundary when reading data, as well as writing it (see this article for further information).

In a very simple application, you can work directly with an ISessionFactory and create your own session and transactions. The TinyNH TinyNH.DemoStore.ProductImporter console application provides an example of how you might work with NHibernate in a simple "throwaway" application. Here, the session and transaction are managed explicitly:

Look at ProductImporter/Importer.cs on github if you can't see the code in-line above.

Context Sessions

The application code shown above takes full responsibility for the session life cycle  from opening the session and beginning a transaction to committing and rolling back the transaction.

In other scenarios, it makes sense for the session and transaction to be managed externally to the code that uses the session to do its work. To do this, we introduce a mechanism that makes an “ambient” session available in the background to anything that needs to use it. The life cycle of this session is tied to a given scope or context. One obvious scope would be the lifetime of a web request within an ASP.Net application. Other examples include an NServiceBus handler or similar command handler, anywhere where objects are loaded and saved within a logical “unit of work”.

Sharing a session within a given context brings a number of benefits:
  • You don’t want to have repetitive session and transaction management code scattered throughout your application code.
  • It is less efficient for separate pieces to start and close their own session when the work could be completed within a single shared session.
  • NHibernate's first-level cache can be leveraged more effectively, reducing the number to trips to the database if separate pieces of code need the same object
  • NHibernate's lazy loading mechanism - where an object’s related objects are loaded on-demand as properties and collections are navigated - requires a session to be kept active in the background, perhaps after the method responsible for loading the objects has exited. For example, an ASP.Net MVC controller action method may load some objects and assemble a  model for display in the view. When the view is rendered, child objects associated with objects loaded by the controller may need to be loaded as they are accessed within the view, a good example of where a session needs to be managed outside of the code that uses it. 
Bear in mind that there may be scenarios where certain objects absolutely should be saved in a separate session and transaction, e.g. you are logging user actions at the beginning of a web request and you don’t want this to be rolled back as a result of an error occurring further down the line.

Context Session Management

We need two mechanisms in place to make our ambient session available during a given context:
  • Somewhere to store the current session
  • Something to co-ordinate everything, starting the session / transaction when the scope begins, committing the transaction when the scope ends or rolling back the transaction if an error occurs.
The first element is built-in to NHibernate, in the form of ISessionFactory's GetCurrentSession method. See the documentation about context sessions for background.

NHibernate must be configured with the strategy that it will use to store the context session. ConfigurationBuilder, responsible for initialising our NHibernate Configuration initialises our configuration to use CallSessionContext, a sensible default for tests and offline applications. This is overridden in our web application start-up code to use an implementation of ICurrentSessionContext for web applications:

Look at ConfigurationBuilder.cs on github if you can't see the code in-line above.

LazyWebSessionContext is TinyNH's custom implementation of ICurrentSessionContext. It supports a mechanism whereby starting a session and transaction is deferred until it is actually used. This ensures that we don't pay the price of opening a database connection and starting a transaction during a request that doesn't need to access the database.

NHibernate can't get the current session by itself however. The next piece in the jigsaw is a mechanism to coordinate the session in line with the lifetime of our context.

This is handled by LazyWebSessionContextModule.cs, an HttpModule:

Look at LazyWebSessionContextModule.cs on github if you can't see the code in-line above.

An HttpModule is not the only mechanism available. You could add session management functionality directly to the Application_BeginRequest, Application_EndRequest and Application_Error methods of your global.asax file.ASP.Net MVC ActionFilters and the Controller class itself also provide hook methods that could be used in a similar way. An HttpModule is a useful one-size-fits-all mechanism however, you may be running MVC controllers, Web API controllers and ASP.Net handlers in your application.

Accessing the Session

With the above in place, NHibernate, LazyWebSessionContext and LazyWebSessionContextModule will work together to manage your sessions and transactions. It remains to add a point where your application code can access the current session. In keeping with it's structurally simple architecture, TinyNH adds a CurrentSession property to Global.asax.cs and an additional convenience property to a shared controller base class AppController.cs. There are of course other mechanisms that could be used to make this dependency available to classes that need it - just configure your IoC container to resolve the ISession from the ISessionFactory (an example of how to do this may be added at some point).

How to do it

If you are using NHibernate in a web application, you can add lazy context session management as follows:

1. Add LazyWebSessionContext.cs and LazyWebSessionContextModule.cs to your project, within the same namespace as the ConfigurationBuilder class and other NHibernate infrastructure code.

2. Modify your web application start up code, using ConfigurationBuilder to configure NHibernate to use LazyWebSessionContext - see Global.asax.cs

3. Configure your application to use the LazyWebSessionContextModule HttpModule by adding the module to the configuration/system.webServer/modules section - see web.config for details.

If you are using IIS6 or need to run your web application in the older Visual Studio Development Server, then the module needs to be added to the configuration/system.web/httpModules section instead.

4. Define a point where your application code can access the context session as outlined above.

4 comments:

  1. INTERNATIONAL CONCEPT OF WORK FROM HOME
    Work from home theory is fast gaining popularity because of the freedom and flexibility that comes with it. Since one is not bound by fixed working hours, they can schedule their work at the time when they feel most productive and convenient to them. Women & Men benefit a lot from this concept of work since they can balance their home and work perfectly. People mostly find that in this situation, their productivity is higher and stress levels lower. Those who like isolation and a tranquil work environment also tend to prefer this way of working. Today, with the kind of communication networks available, millions of people worldwide are considering this option.

    Women & Men who want to be independent but cannot afford to leave their responsibilities at home aside will benefit a lot from this concept of work. It makes it easier to maintain a healthy balance between home and work. The family doesn't get neglected and you can get your work done too. You can thus effectively juggle home responsibilities with your career. Working from home is definitely a viable option but it also needs a lot of hard work and discipline. You have to make a time schedule for yourself and stick to it. There will be a time frame of course for any job you take up and you have to fulfill that project within that time frame.

    There are many things that can be done working from home. A few of them is listed below that will give you a general idea about the benefits of this concept.

    Baby-sitting
    This is the most common and highly preferred job that Women & Men like doing. Since in today's competitive world both the parents have to work they need a secure place to leave behind their children who will take care of them and parents can also relax without being worried all the time. In this job you don't require any degree or qualifications. You only have to know how to take care of children. Parents are happy to pay handsome salary and you can also earn a lot without putting too much of an effort.

    Nursery
    For those who have a garden or an open space at your disposal and are also interested in gardening can go for this method of earning money. If given proper time and efforts nursery business can flourish very well and you will earn handsomely. But just as all jobs establishing it will be a bit difficult but the end results are outstanding.

    Freelance
    Freelance can be in different wings. Either you can be a freelance reporter or a freelance photographer. You can also do designing or be in the advertising field doing project on your own. Being independent and working independently will depend on your field of work and the availability of its worth in the market. If you like doing jewellery designing you can do that at home totally independently. You can also work on freelancing as a marketing executive working from home. Wanna know more, email us on workfromhome.otr214425@gmail.com and we will send you information on how you can actually work as a marketing freelancer.


    Internet related work
    This is a very vast field and here sky is the limit. All you need is a computer and Internet facility. Whatever field you are into work at home is perfect match in the software field. You can match your time according to your convenience and complete whatever projects you get. To learn more about how to work from home, contact us today on workfromhome.otr214425@gmail.comand our team will get you started on some excellent work from home projects.


    Diet food
    Since now a days Women & Men are more conscious of the food that they eat hence they prefer to have homemade low cal food and if you can start supplying low cal food to various offices then it will be a very good source of income and not too much of efforts. You can hire a few ladies who will help you out and this can be a good business.

    Thus think over this concept and go ahead.

    ReplyDelete

  2. Excellent informative article! Thank you for your work, the code is well demonstrated, and even it was interesting to read the comments)
    Richard Brown data room due diligence

    ReplyDelete
  3. Java Online Training Java Online Training Java Online Training Java Online Training Java Online Training Java Online Training

    Hibernate Online Training Hibernate Online Training Spring Online Training Spring Online Training Spring Batch Training Online Spring Batch Training Online

    ReplyDelete