繁体   English   中英

在NHibernate中达到连接池限制

[英]Connection Pool Limit reached in NHibernate

对于使用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请求Begin和End处理程序

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个连接。

请销毁所有打开的连接,这通常是达到池限制的原因...

还正确实现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();
    }
}

很棒,您在发表评论之前就进行了测试...将评论作为答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM