У меня есть приложение MVC, развернутое на 3 отдельных серверах (тестовая, промежуточная и производственная среда). Тестирование и сервер Балетмейстера делают хорошо, но время от времени, сервер производства вытаскивает эту ошибкуNhibernate, SQL Server и IIS 7.5 Утечка соединения: время ожидания до получения соединения из пула приложений
System.InvalidOperationException таймаута. Период ожидания истекает до получения соединения> из пула. Возможно, это произошло из-за того, что все объединенные соединения были в> использовании и максимальный размер пула.
Полная трассировка стека, зафиксированная elmah, показана ниже.
Сервер производства на SQL Server 2008 и IIS 7.5.
разъем Driver My Nhibernate является, как показано ниже
<?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.
Реализация подразумевает переписывание большинства методов в моей бизнес-логике.
Я волнуюсь, потому что это не единственное приложение, которое я написал таким образом, и, кроме того, тестовая и промежуточная среда в порядке.Из отчета о регистрации это часто происходит, когда сайт находится на низком трафике, например, 6:00 утра, 3.00 утра, но время не фиксировано.
Просьба помочь
Update Это мой autofac Dependency распознаватель (я могу видеть из внутреннего исключения, что 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));
}
}
Спасибо за это @Dmitry S, но текущая сессия была инициирована вне оператора if. Я имею в виду, что у нас есть только один экземпляр, но множественное назначение в выражении if. –
'sessionFactory.OpenSession()' инициализирует новый сеанс для каждого присваивания. –