2011-06-16 70 views
0

我在使用Nhibernate的MVC Web应用程序中遇到了一些奇怪的问题。ASP Mvc Nhibernate问题

没有1一致的错误,我把随机的人的越来越负载:

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

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

一个例子是有一个客户对象,其中包含一个地址对象,接触对象,朋友反对,之前的订单对象等等...

所以整个对象被读出,然后映射到UI域模型,然后显示在页面内的不同部分中。每个部分可以通过ajax单独更新,因此您可以更新1个部分,或者您可以将它们全部更新。当我试图将它们全部结合在一起时,似乎主要给我带来问题(所以2-4个同时发生的ajax请求会坚持模型的大块)。

现在我有集成测试工作正常,它只是测试实体的持久性和检索。作为一个整体,个人和所有通过罚款,但在网络应用程序,他们似乎继续抛出随机例外,并最初拒绝坚持以外的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的关系,但在逻辑上是有意义
  • 健保bernate域实体经过映射层成为UI域实体,反之亦然。这里的问题在于,在使用1-1映射的情况下,如果坚持示例Address,则必须使用正确的Id生成Surrogate Customer对象,然后进行合并。
  • 有阿贾克斯的ALOT与整体模型(我说话像有一个单一的模式,但也有相当多的顶级车型,只是一个是最重要的)
+2

您可以发布关于如何保存对象和事务管理的代码示例吗? – Chris 2011-06-16 17:54:27

+0

您是否有可能无意中嵌套您的会话/交易和/或不打开您认为自己的会话/开始交易?你在多个地方有会话/事务逻辑吗?你有没有想过使用HttpModule使用session-per-request模式? – csano 2011-06-16 23:23:42

回答

0

一些大块交易笔记可能会有所帮助。我使用windsor,但想象的概念是相同的。听起来好像可能有一些事情的组合。

  • SessionFactory应该创建为单例,并且会话应该是每个Web请求。喜欢的东西:

    Bind<ISessionFactory>() 
         .ToProvider<SessionFactoryBuilder>() 
         .InSingletonScope(); 
    
        Bind<ISession>() 
         .ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()) 
         .InRequestScope(); 
    
  • 注意保持交易开放太久,让他们为短暂,尽量避免死锁。

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