如何在事务中包装延迟加载?

时间:2011-06-05 20:37:00

标签: nhibernate ninject ninject-2

我正在使用nhibernate和nhibernate配置文件继续抛出此警报。

Use of implicit transactions is discouraged"

我实际上是通过ninject

将事务中的所有内容包装起来
  public class NhibernateModule : NinjectModule
    {
        public override void Load()
        {
            Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
            Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope()
                                                                                      .OnActivation(StartTransaction)
                                                                                      .OnDeactivation(CommitTransaction);
        }

        public void CommitTransaction(ISession session)
        {

            if (session.Transaction.IsActive)
            {
                session.Transaction.Commit();
            }

        }

        public void StartTransaction(ISession session)
        {
            if (!session.Transaction.IsActive)
            {
                session.BeginTransaction();
            }
        }
    }

所以这应该包装一个事务中的所有东西,它似乎适用于任何非延迟加载的东西。

如果它是延迟加载但我收到错误。我做错了什么。

1 个答案:

答案 0 :(得分:1)

事实上,这仍然是一个隐含的交易,或者相对接近它。注入器对激活和停用之间发生的所有事情一无所知,即使状态不正确或已损坏,也会很乐意尝试提交所有更改。

我看到的是你实际上是在试图作弊,只是让Ninject在每个请求开始时自动启动一个事务,并在每个请求结束时提交事务,希望它能阻止NH抱怨。由于以下几个原因,这是非常糟糕的设计:

  1. 即使根本没有使用会话(即打开虚假连接),您也在强制进行交易。
  2. 没有异常处理 - 如果操作失败或回滚,清理代码会忽略它并尝试提交。
  3. 如果您尝试使用TransactionScope,这将造成严重破坏,因为范围将在NH交易之前完成。
  4. 您失去了对交易实际发生时间的所有控制权,并放弃了(例如)在单​​个请求中拥有多个交易的能力。
  5. NH Profiler完全正确。这不适合使用NH交易。实际上,如果你是延迟加载,那么当你仍在迭代结果时,事务可能最终被提交 - 这不是一个好的情况。

    如果你想在事务逻辑上使用有用的抽象,并且不想使用ISession个对象,那么使用Unit Of Work pattern - 这就是它的设计目标

    否则,请正确编码您的交易,并在实际代表交易的操作周围加上using子句。是的,这是额外的工作,但你不能轻易地欺骗它。