在NHibernate中达到连接池限制

时间:2015-03-13 20:08:23

标签: c# asp.net-mvc nhibernate connection-pooling structuremap

对于使用NHibernate的MVC应用程序,我在尝试正确处理我的工作单元的生命周期(认为这对我的UoW来说是一个问题)时遇到了问题。有多线程的机会所以它也需要考虑到这一点。我决定尝试让NHibernate管理连接而不是在我的依赖注入器(StructureMap)中进行连接,但现在我遇到了连接池限制的问题。

我已经简化了部分内容以便发布代码,但希望它有助于了解我所缺少的内容......

NHibernate配置

var cfg = new Configuration()
    .DataBaseIntegration(x =>
    {
        x.ConnectionStringName = "ApplicationConnectionStringName";
        x.Dialect<CustomMsSql2008Dialect>(); //Inherits from MsSql2008GeographyDialect
        x.IsolationLevel = IsolationLevel.RepeatableRead;
        x.BatchSize = 100;
    })
    .CurrentSessionContext<WebSessionContext>()
    .Cache(c =>
    {
        c.Provider<SysCacheProvider>();
        c.UseQueryCache = true;
    });

工作单元

public class NHibernateUnitOfWork : INHibernateUnitOfWork
{
    private ITransaction transaction;
    private bool isDisposed;
    private readonly ISessionFactory source;

    public NHibernateUnitOfWork(ISessionFactory source)
    {
        this.source = source;
        VerifyIsNotDisposed();
        if (CurrentSessionContext.HasBind(source))
        {
            CurrentSession = source.GetCurrentSession();
            this.transaction = CurrentSession.Transaction;
        }
        else
        {
            CurrentSession = this.source.OpenSession();
            CurrentSessionContext.Bind(CurrentSession);
            BeginNewTransaction();
        }
    }

    public ISession CurrentSession { get; private set; }

    public void Commit()
    {
        VerifyIsNotDisposed();
        this.transaction.Commit();
        BeginNewTransaction();
    }

    private void BeginNewTransaction()
    {
        if (this.transaction != null)
        {
            this.transaction.Dispose();
        }
        this.transaction = CurrentSession.BeginTransaction();
    }

    public void Rollback()
    {
        VerifyIsNotDisposed();
        this.transaction.Rollback();
        BeginNewTransaction();
    }

    private void VerifyIsNotDisposed()
    {
        if (this.isDisposed) throw new ObjectDisposedException(GetType().Name);
    }

    public void Dispose()
    {
        if (this.isDisposed) return;
        this.transaction.Dispose();
        CurrentSessionContext.Unbind(this.source);
        CurrentSession.Dispose();
        this.isDisposed = true;
    }
}

通过StructureMap请求开始和结束处理程序

public class StructureMapScopeModule : IHttpModule {
    public void Dispose() {
    }

    public void Init(HttpApplication context) {
        context.BeginRequest += (sender, e) =>
        {
            StructuremapMvc.StructureMapDependencyScope.CreateChildContainer();
            var unitOfWork = StructuremapMvc.StructureMapDependencyScope.Container.GetInstance<IUnitOfWork>();
        };
        context.EndRequest += (sender, e) => {
            var unitOfWork = StructuremapMvc.StructureMapDependencyScope.Container.GetInstance<IUnitOfWork>();
            unitOfWork.Commit();
            HttpContextLifecycle.DisposeAndClearAll();
            StructuremapMvc.StructureMapDependencyScope.DisposeChildContainer();
        };
    }
}

现在运行查询以获得连接数几乎可以提供125个连接。

1 个答案:

答案 0 :(得分:0)

请关掉所有打开的连接,这通常是达到游泳池限制的原因......

正确实现IDisposable并不像看起来那么简单......下面是我正在使用的示例实现(从SO上的答案中复制它)

using System;

namespace AlgoSys.Common.SharedUtils
{
    public abstract class Disposable : IDisposable
    {
        private bool _disposed;

        // Dispose() calls Dispose(true)
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        // NOTE: Leave out the finalizer altogether if this class doesn't 
        // own unmanaged resources itself, but leave the other methods
        // exactly as they are. 
        ~Disposable()
        {
            // Finalizer calls Dispose(false)
            Dispose(false);
        }

        // The bulk of the clean-up code is implemented in Dispose(bool)
        protected virtual void Dispose(bool disposing)
        {
            if(_disposed) return;

            if (disposing)
            {
                OnDispose();
            }


            _disposed = true;
        }

        protected abstract void OnDispose();
    }
}

很棒,你在评论之前测试了它......把评论作为答案。