我是Nhibernate的新手,通过学习它来减慢工作速度。我试图实现一个会话管理器类来帮助我获取db调用的会话。下面是它的代码。有人可以说,如果这在架构上是正确的,并预见到任何可扩展性或性能问题吗?
public static class StaticSessionManager
{
private static ISession _session;
public static ISession GetCurrentSession()
{
if (_session == null)
OpenSession();
return _session;
}
private static void OpenSession()
{
_session = (new Configuration()).Configure().BuildSessionFactory().OpenSession();
}
public static void CloseSession()
{
if (_session != null)
{
_session.Close();
_session = null;
}
}
}
在我的数据提供程序类中,我使用以下代码来获取数据。
public class GenericDataProvider<T>
{
NHibernate.ISession _session;
public GenericDataProvider()
{
this._session = StaticSessionManager.GetCurrentSession();
}
public T GetById(object id)
{
using (ITransaction tx = _session.BeginTransaction())
{
try
{
T obj = _session.Get<T>(id);
tx.Commit();
return obj;
}
catch (Exception ex)
{
tx.Rollback();
StaticSessionManager.CloseSession();
throw ex;
}
}
}
}
然后
public class UserDataProvider : GenericDataProvider<User>
{
public User GetUserById(Guid uid)
{
return GetById(uid)
}
}
Page
中的最终用法UserDataProvider udp = new UserDataProvider();
User u = udp.GetUserById(xxxxxx-xxx-xxx);
这是正确的吗?在单个页面中实例化大量数据提供程序会导致问题吗?
我现在也面临一个问题,如果我同时从多台机器执行相同的读取操作,Nhibernate会抛出随机错误 - 我认为这是由于交易造成的。
请建议。
答案 0 :(得分:2)
如果您有null
会话,我可以看到您正在构建会话工厂。您只应在应用程序启动时调用BuildSessionFactory()
一次。
您执行此操作取决于您,有些人在方法SessionFactory
中的Global.asax内部构建application_start
,或者在您的情况下为sessionFactory
而不是{session
构建静态属性{1}}课程中的{1}}。
我怀疑您的错误是由于您的会话工厂正在多次构建!
另一点是,有些人会在每个请求开始时打开一个事务StaticSessionManager
,并在每个请求结束时打开_session.BeginTransaction()
或commit
。这为您提供了一个工作单元,这意味着您可能会失去
rollback
关于每个方法。所有这些都是开放的辩论,但我使用这种方法99%的代码完全没有问题。