我有一个使用Fluent Nhiberate,SQL Server和autofac的ASP.net mvc应用程序。发布我的应用程序后,IIS会创建许多未关闭的SQL Server连接。
我的SessionManager
课程:
public class SessionPerRequestModule : IHttpModule
{
private static readonly string NH_SESSION_ISOK_KEY = "NH_SESSION_ISOK";
private static readonly string NH_SESSION_PREFFIX_KEY = "NH_SESSION";
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.EndRequest += CtxEndRequest;
context.Error += CtxOnError;
}
private void CtxOnError(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
context.Items[NH_SESSION_ISOK_KEY] = false;
}
private void CtxEndRequest(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
foreach (string dbKey in DatabaseKeys.AllKeys)
{
ISession session = GetCurrentSession(dbKey, false);
CloseSession(session);
SetSession(dbKey, null);
}
}
public static bool IsOnError
{
get { return Convert.ToBoolean(HttpContext.Current.Items[NH_SESSION_ISOK_KEY]); }
set { HttpContext.Current.Items[NH_SESSION_ISOK_KEY] = value; }
}
private static ISession OpenSession(string dbKey)
{
try
{
var interceptor = new SetSystemPropertiesInterceptor(
() => DependencyResolver.Current.GetService<IAuthenticationService>()
);
ISession session;
session = NHibernateSessionHelper.GetFactory(dbKey).OpenSession(interceptor);
if (session == null)
throw new InvalidOperationException(string.Format("Call to factory.OpenSession('{0}') returned null.", dbKey));
session.FlushMode = FlushMode.Never;
session.BeginTransaction();
interceptor.SetSession(session);
return session;
}
catch (Exception ex)
{
throw new Exception(string.Format("Error on database with key '{0}'", dbKey), ex);
}
}
private static void CloseSession(ISession session)
{
if (session != null)
{
try
{
if (!IsOnError)
{
if (session.Transaction != null && session.Transaction.IsActive)
session.Transaction.Commit();
else
session.Flush();
}
else
session.Transaction.Rollback();
}
finally
{
session.Dispose();
}
}
}
public static ISession GetCurrentSession(string dbKey)
{
return GetCurrentSession(dbKey, true);
}
public static ISession GetCurrentSession(string dbKey, bool createIfNotFound)
{
string fullKey = FormatFullContextKey(dbKey);
ISession session = HttpContext.Current.Items[fullKey] as ISession;
if (createIfNotFound && session == null)
{
session = OpenSession(dbKey);
SetSession(dbKey, session);
}
return session;
}
private static void SetSession(string dbKey, ISession session)
{
string fullKey = FormatFullContextKey(dbKey);
HttpContext.Current.Items[fullKey] = session;
}
private static string FormatFullContextKey(string dbKey)
{
return string.Concat(NH_SESSION_PREFFIX_KEY, "_", dbKey);
}
}
我的NHibernate会话助手的一部分:
factory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.FormatSql().ShowSql().AdoNetBatchSize(50).ConnectionString(c => c.FromConnectionStringWithKey(databaseKey)))
.Mappings(x =>
x.FluentMappings.AddFromAssemblyOf<ColaboradorMapping>()
.Conventions.AddFromAssemblyOf<CustomTypeConvention>()
).BuildSessionFactory();
factories.Add(databaseKey, factory);
我的Autofac注射:
public static IContainer RegisterAllDependencies()
{
var builder = new ContainerBuilder();
builder.Register(x => new VejoSeriesDb(SessionPerRequestModule.GetCurrentSession(DatabaseKeys.VejoSeriesDb))).As<IVejoSeriesDb>();
builder.Register(x => new StarkDb(SessionPerRequestModule.GetCurrentSession(DatabaseKeys.MySQLStarkDb))).As<IStarkDb>();
//session mongo
builder.Register(x => new StarkMongoDb()).As<IStarkMongoDb>();
builder.RegisterAssemblyTypes(typeof(IUsuarioSerieN).Assembly)
.AsImplementedInterfaces();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterFilterProvider();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
return container;
}
我忘记关闭连接的地方了?