Reputation: 5379
A have an action on my MVC application that have an id
and returns a person's name.
What is the best practice for that? I'm following NHProf tips, but code sounds a little strange or something for me.
using (var session = Helper.SessionFactory.OpenStatelessSession())
{
using (var tran = session.BeginTransaction(IsolationLevel.ReadCommitted))
{
return session.Query<Person>().Where(x => x.Id == id).Select(x => x.Name).SingleOrDefault();
tran.Rollback();
}
}
Upvotes: 5
Views: 4290
Reputation: 15579
do not create multiple sessions over one HTTP request, ideally what you need to do is open a session and a corresponding transaction at the request scope and use this session throughout all your actions.
Here is a blogpost explaining how to achieve it: http://hackingon.net/post/NHibernate-Session-Per-Request-with-ASPNET-MVC.aspx
I would suggest the use of an IOC container and create a class that creates the session for you and scope this class to the request scope.
There are lots of resources on the web to approach this problem.. Google it..
Upvotes: 0
Reputation: 1112
The following is how I would approach this select:
using (var session = Helper.SessionFactory.OpenStatelessSession())
using (var tran = session.BeginTransaction(IsolationLevel.ReadCommitted))
{
try
{
string personName = session.Query<Person>()
.Where(x => x.Id == id)
.Single(x => x.Name);
tran.Commit();
return personName;
}
catch(Exception ex)
{
// handle exception
tran.Rollback();
}
}
This SO answer gives good advice to dealing with transaction commits:
NHibernate - Is ITransaction.Commit really necessary?
With regards to your LINQ this is an interesting article on how not to approach queries using the extension method style syntax:
http://compiledexperience.com/blog/posts/how-not-to-use-linq
Upvotes: 0
Reputation: 4079
The NHProf alert page explains it quite well I think -
http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions
Basically it's saying if you don't manage transactions yourself, the database will create an "implicit transaction" and auto-commit for every statement, including queries. The misconception is that transactions are useful only for insert / update operations.
In your example above, it's not much of an issue as your transaction only executes a single statement anyway. If your method was running several statements however it would be good practice to wrap them in a transaction.
Upvotes: 4