【发布时间】:2016-06-05 00:49:24
【问题描述】:
我有一个 MVC 应用程序部署在 3 个独立的服务器(测试、暂存和生产环境)上。测试和暂存服务器运行良好,但偶尔,生产服务器确实会出现此错误
System.InvalidOperationException 超时已过。在从池中获取连接之前已经过了超时时间。这可能是因为所有池连接都在>使用中并且已达到最大池大小。
elmah 捕获的完整堆栈跟踪如下所示。
生产服务器在 SQL Server 2008 和 IIS 7.5 上。
我的 Nhibernate Driver 连接器如下图所示
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect,NHibernate</property>
<property name="adonet.batch_size">0</property>
<property name="show_sql">true</property>
<mapping assembly="BusinessLogic"/>
</session-factory>
</hibernate-configuration>
这是我的获取当前会话方法
public static ISession GetCurrentSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CURRENT_NHIBERNATE_SESSION_KEY] as ISession;
if (currentSession == null)
{
currentSession = sessionFactory.OpenSession();
context.Items[CURRENT_NHIBERNATE_SESSION_KEY] = currentSession;
}
if (currentSession.Connection.State == System.Data.ConnectionState.Closed)
{
currentSession = sessionFactory.OpenSession();
}
if (!currentSession.IsConnected)
{
currentSession = sessionFactory.OpenSession();
}
if (!currentSession.IsOpen)
{
currentSession = sessionFactory.OpenSession();
}
if (currentSession.IsDirty())
{
currentSession.Clear();
}
return currentSession;
}
我的所有业务逻辑都使用了 IRepository 模式。我的一种方法如下所示:
public IList<CourseRequirement> getCourseRequirement(int requirementId)
{
ISession session = _courseRequirment.CurrentSession;
var cr = session.QueryOver<CourseRequirement>().Where(x => x.RequirementId == requirementId);
return cr.List<CourseRequirement>();
}
此外,我正在使用 autofac 进行依赖注入。每次发生时,我也可以在内部异常中看到这一点。
System.InvalidOperationException:尝试执行时出错 创建一个“ASSEMBLY.Controllers.AccountController”类型的控制器。 确保控制器有一个无参数的公共构造函数。 ---> Autofac.Core.DependencyResolutionException:在类型上调用构造函数“Void .ctor()”时引发异常 'NHibernateRepository`2'。 ---> 超时。超时时间 在从池中获取连接之前经过。这可能有 发生是因为所有池连接都在使用中并且最大池大小 达到了。 (有关详细信息,请参阅内部异常。)---> System.InvalidOperationException:超时已过期。超时时间 在从池中获取连接之前经过。这可能有 发生是因为所有池连接都在使用中并且最大池大小 已到达。
我做了什么
我已经检查了这些link、link 等等。 how-to-fix-sql-connection-leaks-in-this-code 等其他人建议将 sql 放入 using 语句中。 几乎所有的链接都表明应用程序中存在连接泄漏,并建议将所有事务放在 using 语句中。
实现意味着重写我的业务逻辑中的大多数方法。
我很担心,因为这不是我用这种方式编写的唯一应用程序,除了测试和登台环境都很好。从日志报告来看,这通常发生在网站流量较低时,例如早上 6:00、凌晨 3:00 但时间不固定。
请帮忙
更新 这是我的 autofac 依赖解析器(我可以从内部异常中看到 autofac 偶尔无法实例化某些服务
public class FormDependencyResolver
{
public static void RegisterDependencies()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.Register(c =>
//register FakeHttpContext when HttpContext is not available
HttpContext.Current != null ?
(new HttpContextWrapper(HttpContext.Current) as HttpContextBase) :
(new FakeHttpContext("~/") as HttpContextBase))
.As<HttpContextBase>()
.InstancePerLifetimeScope();
builder.Register(c => c.Resolve<HttpContextBase>().Request)
.As<HttpRequestBase>().InstancePerLifetimeScope();
builder.Register(c => c.Resolve<HttpContextBase>().Response)
.As<HttpResponseBase>()
.InstancePerLifetimeScope();
builder.Register(c => c.Resolve<HttpContextBase>().Server)
.As<HttpServerUtilityBase>()
.InstancePerLifetimeScope();
builder.Register(c => c.Resolve<HttpContextBase>().Session)
.As<HttpSessionStateBase>()
.InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(NHibernateRepository<,>)).As(typeof(IRepository<,>)).InstancePerLifetimeScope();
builder.RegisterType<AsyncService>().As<IAsyncService>().InstancePerLifetimeScope();//.InstancePerLifetimeScope();
builder.RegisterType<SMSSender>().As<ISMSSender>().InstancePerLifetimeScope();
builder.RegisterType<SMSAccount>().As<ISMSAccount>().InstancePerLifetimeScope();
builder.RegisterType<BusinessLogic.Services.AuthenticationService>().As<IAuthenticationService>().InstancePerLifetimeScope();
builder.RegisterType<PageHelper>().As<IPageHelper>().InstancePerLifetimeScope();
builder.RegisterType<UtilityService>().As<IUtilityService>().InstancePerLifetimeScope();
builder.RegisterType<WebWorker>().As<IWebWorker>().InstancePerLifetimeScope();
builder.RegisterType<DateTimeHelper>().As<IDateTimeHelper>().InstancePerLifetimeScope();
builder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();
builder.RegisterType<AuditService>().As<IAuditService>().InstancePerLifetimeScope();
builder.RegisterType<HtmlHelper>().InstancePerDependency();
builder.RegisterType<PaymentService>().As<IPaymentService>().InstancePerLifetimeScope();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
【问题讨论】:
标签: c# asp.net-mvc nhibernate memory-leaks autofac