ASP Mvc Nhibernate问题

时间:2011-06-16 17:48:18

标签: asp.net-mvc nhibernate transactions

我在MVC网络应用程序中遇到了Nhibernate的一些奇怪问题。

没有一致的错误,我不断加载随机错误:

  • 交易未成功启动
  • 不允许启动新请求,因为它应该带有有效的事务描述符
  • 意外的行数:-1;预期:1

为了给设置提供一些上下文,我使用Ninject对DI会话和其他Nhibernate相关的对象,目前我正在使用RequestScope但是我已经尝试了SingletonScope。我有一个庞大而复杂的数据模型,它作为一个整体读出,但保留在不同的部分,因为这些都可以单独编辑和保存。

一个例子是拥有一个Customer对象,它包含一个地址对象,一个联系对象,一个朋友对象,以前的订单对象等等......

因此读出整个对象,然后映射到UI域模型,然后在页面内的不同部分中显示。每个部分都可以通过ajax单独更新,因此您可以更新1个部分,也可以一起更新它们。当我试图将它们全部保持在一起时,似乎主要是给我提出问题(所以2-4个同步的ajax请求持久保存模型的大块)。

现在我的集成测试工作正常,只测试实体的持久性和检索。作为一个整体,单独和所有传递都很好,但是在Web应用程序中,它们似乎一直在抛出随机异常,并且最初拒绝在Nhibernate缓存之外持久存在。我通过在交易中包装大多数工作单元找到了一种解决方法,这使得数据保持不变但开始在混合中添加新错误。

最初我在考虑从项目中删除Nhibernate,因为虽然我真的想要它的持久性/缓存层,但它似乎对我的域名似乎没有足够的灵活性,这看起来很奇怪,因为我以前使用它没有太多问题,虽然它不喜欢1-1映射。

所以有人在ASP MVC应用程序中有这样的flakey事务/ nhibernate问题......我知道这可能有点模糊,因为错误不指向一件事,并且它并不总是错误,所以它就像在黑暗中刺伤一样,但我没有想法,所以任何帮助都会很棒!

- 更新 -

由于项目很大,我无法发布所有相关代码,但事务位看起来像:

using (var transaction = sessionManager.Session.BeginTransaction(IsolationLevel.ReadUncommitted))
            {
                try
                {
                    // Do unit of work
                    transaction.Commit();

                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }

我在这个项目中遇到的一些主要问题源于:

  • 复合键有1-1个关系,但从逻辑上说它是有意义的
  • Nhibernate域实体通过映射层成为UI域实体,然后在保存时反之亦然。这里的问题是,对于1-1映射,当持久化示例地址时,我必须使用正确的Id生成一个Surrogate Customer对象,然后合并。
  • 有很多Ajax处理整个模型的大块(我说有一个单一的模型,但有很多顶级模型,只有一个是最重要的)

1 个答案:

答案 0 :(得分:0)

一些可能有帮助的说明。我使用windsor,但想象一下概念是一样的。听起来可能有各种各样的事情。

  • SessionFactory应该创建为singleton,session应该是每个web请求。类似的东西:

        Bind<ISessionFactory>()
            .ToProvider<SessionFactoryBuilder>()
            .InSingletonScope();
    
        Bind<ISession>()
            .ToMethod( context => context.Kernel.Get<ISessionFactory>().OpenSession() )
            .InRequestScope();
    
  • 小心保持交易开放时间过长,尽可能缩短交易时间以避免死锁。

  • 使用NHProf之类的工具检查您的查询是否按预期运行。通常人们会加载过多的图形,这会影响性能并可能造成死锁。
  • 检查映射是否有类似not.lazyload()的内容,并查看您是否确实需要查询中的其他数据并将结果保持为最小值。检查查询执行计划并确保有足够的索引。
  • 我遇到了缓存mvc3操作过滤器的问题,这意味着事务并不总是启动,但会尝试关闭导致问题。将我的所有事务提交移动到控制器中的ActionResults中,以使事务尽可能短并接近操作。
  • 检查映射中的级联,并将更新保持在最低限度。