5

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();
    }
}
4

3 回答 3

4

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.

于 2012-05-10T13:12:42.627 回答
0

不要在一个 HTTP 请求上创建多个会话,理想情况下,您需要做的是在请求范围内打开一个会话和相应的事务,并在所有操作中使用此会话。

这是一篇解释如何实现它的博文:http: //hackingon.net/post/NHibernate-Session-Per-Request-with-ASPNET-MVC.aspx

我建议使用 IOC 容器并创建一个为您创建会话的类,并将该类的范围限定为请求范围。

网络上有很多资源可以解决这个问题..谷歌它..

于 2012-05-10T17:27:02.687 回答
0

以下是我将如何处理此选择:

    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 answer 为处理事务提交提供了很好的建议:

NHibernate - ITransaction.Commit 真的有必要吗?

关于您的 LINQ,这是一篇关于如何不使用扩展方法样式语法处理查询的有趣文章:

http://compiledexperience.com/blog/posts/how-not-to-use-linq

于 2012-05-10T13:22:35.507 回答