A对我的MVC应用程序执行了一个id
并返回一个人姓名的操作。
最佳做法是什么?我正在关注NHProf的提示,但代码听起来有些奇怪或适合我。
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();
}
}
答案 0 :(得分:4)
NHProf警报页面很好地解释了我认为 -
http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions
基本上它说如果你不自己管理事务,数据库将创建一个“隐式事务”并自动提交每个语句,包括查询。误解是事务仅对插入/更新操作有用。
在上面的例子中,这不是什么大问题,因为你的事务只执行一个语句。如果你的方法运行了几个语句,那么将它们包装在一个事务中是个好习惯。
答案 1 :(得分:0)
不要在一个HTTP请求上创建多个会话,理想情况下,您需要做的是在请求范围内打开会话和相应的事务,并在所有操作中使用此会话。
这是一篇博客文章,解释了如何实现它:http://hackingon.net/post/NHibernate-Session-Per-Request-with-ASPNET-MVC.aspx
我建议使用IOC容器并创建一个为您创建会话的类,并将此类的范围扩展到请求范围。
网上有很多资源可以解决这个问题.Google it ..
答案 2 :(得分:-1)
以下是我如何处理此选择:
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();
}
}
这个SO答案为处理事务提交提供了很好的建议:
NHibernate - Is ITransaction.Commit really necessary?
关于你的LINQ,这是一篇关于如何使用扩展方法样式语法来处理查询的有趣文章:
http://compiledexperience.com/blog/posts/how-not-to-use-linq