我有一个使用Nhibernate连接多个informix数据库的.NET MVC webapi,我使用Repository和工作单元模式。
问题是当发送倍数请求到mvc web api,服务器内存增长并使iis mvc网站停止时。
这是工作单位:
public interface IUnitOfWorkNH: IDisposable
{
void BeginTransaction();
void Commit();
}
public class UnitOfWorkNH : IUnitOfWorkNH
{
private ISessionFactory _sessionFactory;
private ITransaction _transaction;
public ISession Session { get; private set; }
public UnitOfWorkNH(string connection)
{
string stringConnection = ConfigurationManager.AppSettings["NH_DSN"].ToString();
if (!string.IsNullOrEmpty(connection))
{
stringConnection = connection;
}
_sessionFactory = Fluently.Configure()
.Database(OdbcConfiguration.InformixODBC.ConnectionString(stringConnection)
.Driver<NHibernate.Driver.OdbcDriver>()
.Dialect<NHibernate.Dialect.InformixDialect>()
//.ShowSql()
)
.Mappings(m =>
m.FluentMappings
.AddFromAssemblyOf<clsCiaMap>())
.ExposeConfiguration(cfg => new SchemaExport(cfg)
.Create(false, false))
.BuildSessionFactory();
Session = _sessionFactory.OpenSession();
}
public void BeginTransaction()
{
_transaction = Session.BeginTransaction();
}
public void Commit()
{
try
{
// commit transaction if there is one active
if (_transaction != null && _transaction.IsActive)
_transaction.Commit();
}
catch
{
// rollback if there was an exception
if (_transaction != null && _transaction.IsActive)
_transaction.Rollback();
throw;
}
finally
{
Session.Dispose();
}
}
public void Rollback()
{
try
{
if (_transaction != null && _transaction.IsActive)
_transaction.Rollback();
}
finally
{
Session.Dispose();
}
}
public void Dispose()
{
if (this._transaction != null)
{
this._transaction.Dispose();
this._transaction = null;
}
if (this.Session != null)
{
this.Session.Dispose();
Session = null;
}
this._sessionFactory.Dispose();
this._sessionFactory = null;
}
}
这是Repository类:
public interface IRepository<T> where T : class
{
List<T> GetAll();
T GetById(int id);
T GetById(string id);
T GetById(T id);
void Save(T entity);
void Delete(T entity);
}
public class RepositoryNH<T> : IRepository<T> where T : class
{
ISession _session;
public RepositoryNH(ISession session)
{
_session = session;
}
public ISession Session { get { return _session; } }
public List<T> GetAll()
{
return Session.QueryOver<T>().List().ToList();
}
public T GetById(int id)
{
return _session.Get<T>(id);
}
public T GetById(string id)
{
return Session.Get<T>(id);
}
public T GetById(T id)
{
return _session.Get<T>(id);
}
public void Save(T entity)
{
Session.SaveOrUpdate(entity);
Session.Flush();
}
public void Delete(T entity)
{
Session.Delete(entity);
}
}
我不知道在这些课程中是否有错,我需要帮助。
答案 0 :(得分:0)
您正在SessionFactory
类的构造函数中创建新的UnitOfWorkNH
。这表明一次会有多个会话工厂实例。由于这些会话工厂的所有实例都被加载到内存中而从未被丢弃,因此内存使用量不断增加。
另外,建立会话工厂是昂贵的电话。反复创建新的会话工厂将严重影响性能。
理想情况下,您的会话工厂应该是单身人士。它应该在应用程序启动时构建(通过调用BuildSessionFactory()
方法)。然后,应使用相同的会话工厂实例使用ISession
语句创建_sessionFactory.OpenSession()
个实例。
以下是一些原始代码; 不完全是单身,但可能会有所帮助。我仍然建议你考虑使用单身人士。
internal static class NHSessionFactory
{
static Configuration nhConfiguration;
static ISessionFactory nhSessionFactory;
const FlushMode defaultFlushMode = FlushMode.Commit;
internal static ISessionFactory SessionFactory
{
get { return nhSessionFactory; }
}
internal static void CreateSessionFactory()
{
CreateSessionFactory(null);
}
internal static void CreateSessionFactory(string configFilePath)
{
CreateSessionFactory(configFilePath, defaultFlushMode);
}
internal static void CreateSessionFactory(string configFilePath, FlushMode flushMode = defaultFlushMode)
{
if(nhSessionFactory != null)
throw new InvalidOperationNHFacadeException("SessionFactory is already created.");
nhConfiguration = new Configuration();
try
{
if(string.IsNullOrEmpty(configFilePath))
nhConfiguration.Configure();
else
nhConfiguration.Configure(configFilePath);
nhConfiguration.SessionFactory().DefaultFlushMode(flushMode);
}
catch(Exception exception)
{
throw new NHFacadeException("Failed to configure session factory.", exception);
}
try
{
nhSessionFactory = nhConfiguration.BuildSessionFactory();
}
catch(Exception exception)
{
throw new NHFacadeException("Failed to build session factory.", exception);
}
}
internal static void CloseSessionFactory()
{
if(nhSessionFactory != null)
{
if(nhSessionFactory.IsClosed == false)
nhSessionFactory.Close();
nhSessionFactory.Dispose();
nhSessionFactory = null;
}
if(nhConfiguration != null)
nhConfiguration = null;
}
}
请注意,在上面的代码中,方法CreateSessionFactory()
验证了对自身的冗余调用。您需要做的就是在应用程序启动时调用CreateSessionFactory()
并在应用程序退出时调用CloseSessionFactory()
。