gpt4 book ai didi

.net - NHibernate 的 Windows 服务中的多个 SessionFactories

转载 作者:行者123 更新时间:2023-12-04 02:21:34 25 4
gpt4 key购买 nike

我有一个连接到 2 个数据库(一个核心,另一个是日志数据库)的 Web 应用程序。

我现在必须创建一个 Windows 服务,它将使用相同的业务逻辑/数据访问 DLL。但是,当我尝试在服务应用程序中引用 2 个 session 工厂并调用 factory.GetCurrentSession() 方法时,我收到错误消息“没有 session 绑定(bind)到当前上下文”。

有没有人有关于如何做到这一点的建议?

public class StaticSessionManager
{
public static readonly ISessionFactory SessionFactory;
public static readonly ISessionFactory LoggingSessionFactory;

static StaticSessionManager()
{
string fileName = System.Configuration.ConfigurationSettings.AppSettings["DefaultNHihbernateConfigFile"];
string executingPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
fileName = executingPath + "\\" + fileName;
SessionFactory = cfg.Configure(fileName).BuildSessionFactory();

cfg = new Configuration();
fileName = System.Configuration.ConfigurationSettings.AppSettings["LoggingNHihbernateConfigFile"];
fileName = executingPath + "\\" + fileName;
LoggingSessionFactory = cfg.Configure(fileName).BuildSessionFactory();
}
}

配置文件具有以下设置:
<property name="current_session_context_class">call</property>

服务设置工厂:
private ISession _session = null;
private ISession _loggingSession = null;
private ISessionFactory _sessionFactory = StaticSessionManager.SessionFactory;
private ISessionFactory _loggingSessionFactory = StaticSessionManager.LoggingSessionFactory;

...

_sessionFactory = StaticSessionManager.SessionFactory;
_loggingSessionFactory = StaticSessionManager.LoggingSessionFactory;

_session = _sessionFactory.OpenSession();
NHibernate.Context.CurrentSessionContext.Bind(_session);
_loggingSession = _loggingSessionFactory.OpenSession();
NHibernate.Context.CurrentSessionContext.Bind(_loggingSession);

所以最后,我尝试通过以下方式调用正确的工厂:
ISession session = StaticSessionManager.SessionFactory.GetCurrentSession();

任何人都可以提出更好的方法来处理这个问题吗?
提前致谢!

最佳答案

我可以建议的第一件事是让你的ISessionFactory实例为静态。这些应该是单例,因为它们的实例化非常昂贵。

编辑#1

Would you recommend I create the sessions when I need them, or leave them open?


ISession API 在内部处理其连接。一段时间后,如果没有请求与底层数据库交互,连接将关闭,尽管您的 ISession保留其连接实例。一旦它需要与数据库执行一些其他事务,它就会重新打开以前使用的连接。

要回答您的问题,首选方法是 ISession 的实例每页(Web)或每表单(桌面)的 API。例如,假设您有一个会计软件,并且用户对客户进行一些管理。然后,当您的 CustomerMgmtForm加载,您应该提供 ISession 的实例以便它可以加载您的客户、跟踪您的更改、删除和创建的新客户(一旦加入 ISession ,这样当您调用 SaveOrUpdate() 方法时, ISession 就知道它与跟踪更改和 transient 实体。

Why one instance per Page or per Form, do you wonder?



由于 ISession API 跟踪对象发生的每一次更改,想象一下,一旦您加载了您的客户、供应商和其他一些实体,您必须在应用程序中小心。对客户进行的每一项更改,他们对供应商都没有权利。但是这些客户仍然存在,因为它是 ISession 的实例。你已经为你的客户使用了!然后,您的应用程序对内存的需求会随着加载的对象数量而增长。此外,一个已知问题是,当 ISession在内存中增长太大,它可能会导致一些内存泄漏,然后被 NHibernate 视为不再有效的 session ,废弃所有未保存的更改和所有内容,因为跟踪您的实体的 session 现在无效。

除此之外,当您打开 CustomerMgmtForm 时,您将不得不管理客户实体。一旦您关闭了表格,甚至打开了 SuppliersMgmtForm,您更有可能不必跟踪您的客户,您可以在其中管理您的供应商。通过这样做,您将拥有 ISession 的两个实例。 API:第一个 - customerMgmtSession ,另一个 - suppliersMgmtSession .因此,它们永远不应该变得太大而导致内存泄漏,因为它们都有自己的实体要处理或照顾。两者完全相互独立。

按照这种方法,您应该关闭并处理 ISession 的实例。 Windows 窗体的 FormClosing 事件上的 API,或 Web 中的任何等效项。所以现在,在 Windows 服务中,由您来决定什么是理想的情况,并根据您的服务的功能来决定最适合您的需求的位置。

但有一件事,如果您的服务不需要对您的更改或任何实体进行任何跟踪, IStatelessSession API 可能更适合使用。使用它,那么我肯定建议您仅在需要与底层数据库交互时打开或实例化无状态 session ,因为 IStatelessSession 没有用处。保持事件状态,因为它不提供资源来跟踪对您的实体执行的更改。这是主要的,也许只是,如果我没记错的话, ISession 之间的区别和 IStatelessSession蜜蜂。

编辑#2

这样做,如我的 中所述编辑#1 ,也可以帮助您解决问题,因为您无需调用 ISessionFactory.GetCurrentSession() .

我希望这有帮助! =)

关于.net - NHibernate 的 Windows 服务中的多个 SessionFactories,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2931036/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com