ASP.NET NHibernate事务持续时间

Rob*_*ton 4 asp.net nhibernate

目前在我们的ASP.NET应用程序中,每个请求有1个会话,每次加载或更新和对象时都会创建一个事务.见下文:

    public static T FindById<T>(object id)
    {
        ISession session = NHibernateHelper.GetCurrentSession();
        ITransaction tx = session.BeginTransaction();
        try
        {
            obj = session.Get<T>(id);
            tx.Commit();
        }
        catch
        {
            session.Close();
            throw;
        }
        finally
        {
            tx.Dispose();
        }
        return obj;
    }

    public virtual void Save()
    {
        ISession session = NHibernateHelper.GetCurrentSession();
        ITransaction transaction = session.BeginTransaction();
        try
        {
            if (!IsPersisted)
            {
                session.Save(this);
            }
            else
            {
                session.SaveOrUpdateCopy(this);
            }
            transaction.Commit();

        }
        catch (HibernateException)
        {
            if (transaction != null)
            {
                transaction.Rollback();
            }
            if (session.IsOpen)
            {
                session.Close();
            }
            throw;
        }
        finally
        {
            transaction.Dispose();
        }

    }
Run Code Online (Sandbox Code Playgroud)

显然这并不理想,因为这意味着每次加载或保存对象时都会创建与数据库的新连接,从而导致性能开销.

问题:

  • 如果实体已加载到第1级缓存中,GetTransaction()调用将打开数据库连接吗?我怀疑它会......
  • 是否有更好的方法来处理我们的事务管理,因此事务处理更少,因此数据库连接更少?

不幸的是,应用程序代码可能太成熟,无法构建所有类似的东西(在同一个事务中使用get和update all):

using(var session = sessionFactory.OpenSession()) 
using(var tx = session.BeginTransaction()) 
{
    var post = session.Get<Post>(1);
    // do something with post
    tx.Commit();
} 
Run Code Online (Sandbox Code Playgroud)

为每个请求创建一个事务并在请求结束时提交它是一个可怕的想法吗?我猜不到的缺点是它会在非数据库操作发生时绑定一个数据库连接.

Sly*_*Sly 5

每个请求的一个事务被认为是NHibernate的最佳实践.此模式在Sharp Architecture中实现.

但是在Nhibernate方法中,BeginTransaction()doest打开了与DB的连接.连接在第一个真正的sql请求时打开,并在执行查询后立即关闭.所以Nhibernate持有开放连接几秒钟来执行查询.您可以通过SQL事件探查器进行验证.

此外,NHiberante总是尝试使用Sql Servers连接池,为什么打开你的连接可能不是那么昂贵.