对于使用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个连接。
答案 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();
}
}
很棒,你在评论之前测试了它......把评论作为答案。