nhibernate延迟加载使用隐式事务

时间:2012-09-13 11:07:16

标签: nhibernate transactions lazy-loading

这似乎是一个非常常见的问题:我加载了一个具有延迟加载集合的NHibernate对象。 稍后,我会访问该集合以执行某些操作。 我仍然打开nhibernate会话(因为它是按视图管理或其他任何方式)所以它确实有效,但事务已关闭,因此在NHprof中我得到“不鼓励使用隐式事务”。

我理解这条消息,因为我正在使用一个工作单元实现,我可以通过创建一个新事务并将调用包装到其中的延迟加载集合来修复它。

我的问题是这感觉不对...... 我有这个很棒的NHibernate框架,它为我提供了很好的延迟加载,但是如果没有在事务中包装每个属性访问,我就无法使用它。

我已经搜索了很多内容,阅读了大量博客文章,SO上的问题等,但似乎无法找到完整的解决方案。

这就是我所考虑的:

  1. 关闭延迟加载。我认为这很愚蠢,就像在跑车上玩全车,然后只能用eco模式驾驶它。急切加载一切都会损害性能,如果我只是使用id而不是引用那么为什么要麻烦Nhibernate呢?
  2. 保持交易时间更长。交易不应该是长寿的,并且只要视图开放就保持一个开放只会遇到麻烦。
  3. 在事务中包装每个延迟加载属性访问。工作但很臃肿,容易出错。 (即如果我忘记包装一个存取器,那么它仍然可以正常工作。只使用NHProf会告诉我这个问题)
  4. 始终加载我加载初始对象时可能需要的属性的所有数据。同样,这很容易出错,无论是加载不需要的数据(因为后来的访问调用已经被删除),还是没有加载你做的数据
  5. 那么还有更好的方法吗? 任何帮助/想法都赞赏。

1 个答案:

答案 0 :(得分:0)

当我第一次在NHProf中遇到这个警告时,我有同样的感受。在Web应用程序中,我认为最流行的方法是在整个请求期间打开事务(和工作单元)。对于管理事务(以及会话)的桌面应用程序可能会很痛苦。您可以使用自动事务管理框架(例如Castle)并使用应在事务中运行的属性服务方法进行声明。通过这种方法,您可以根据需求将多个操作包装成单个事务。此外,我使用每个视图的会话方法,每个视图打开一个会话和手动事务管理(在这种情况下,我只是忽略了有关隐式事务的探查器警告)。 至于你的考虑:我强烈建议不要2)和3)。 1)和4)是要考虑的要点。但一般的建议是:思考,然后尝试不同的方法,找到一个更适合您的特定情况的解决方案。