我有一段时间试图找出NHibernate中的会话管理问题。我假设我的很多麻烦都是由于缺乏对IoC和AOP概念的了解;至少那是我在思考Fabio Maulo一直指导我的地方。
无论如何,我的问题是我有一个win表单应用程序正在进行“get”调用并将结果绑定到网格。在绑定之后,用户可以执行某种“写入”动作,并且这些动作导致在写入之后会话被关闭以尝试使用每次使用的会话概念。然后用户可以滚动网格,导致延迟加载开始,现在会话已经关闭,我得到一个例外。
我不想让我的观点认识到我的会话,我不想在用户关闭表单时发送KillAllSessions。此外,用户可以在任何给定时间打开多个表单,从而进一步加剧与该方法相关的问题。我基本上希望所有这些都能在“幕后”工作。
所以到目前为止我的想法是拦截延迟加载调用并检查会话是否打开,如果没有重新打开它,获取信息然后重新关闭它。但是,据我所知,这并不多,这本质上就是延迟加载的工作原理。它被代理工厂(NHibernate.Bytecode.Castle)拦截,然后使用会话检索数据。所以我需要实际拦截该调用,然后在重新打开会话后将其传递给原始的预期拦截。这就是我的想法。
我的问题基本上首先是这是正确的方法吗?第二,如果它是我甚至不知道从哪里开始。我从未对方法调用进行任何拦截,我在理论上知道但在实践中却没有。我知道有些图书馆可以做Rhino Commons这样的事情,但我想利用这个机会学习并成为一名更好的程序员。我正在尝试理解AOP和Context Bound Objects,但目前我并没有理解它。你们有些人可以帮助一个人吗?
答案 0 :(得分:7)
我可以想到几个选项:
选项1:在用户与数据交互时保持原始ISession处于打开状态,并在用户完成后立即提交所有更改。这意味着您可能在内存中有大量未提交的更改,而其他用户将看不到挂起的更改。
选项2:将操作拆分为两个工作单元(UOW)。 UOW1只执行读取并负责填充列表。与UOW1关联的ISession保持活动状态以允许延迟加载,例如在向下钻取方案中。 UOW2是为用户编辑创建的一个新的短期ISession。当编辑提交时,原始对象将从UOW1中逐出,UOW1从数据库中提取新副本。
选项3:在每次编辑提交后重新创建列表。这是最简单的解决方案,可能适用于小型数据集。
答案 1 :(得分:2)
我正在开发类似的应用程序。我正在使用一个我保持开放的会话。
每当我写入数据库时,我都使用不关闭底层会话的begin / commit事务。数据库连接仅在事务正在进行时由NHibernate打开。
当用户正在使用表单时,您是否需要关闭会话?
您能否提供有关管理会话,存储库模式等的更多详细信息?