2011-06-16 74 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中,以保持交易儘可能短並接近操作。
  • 檢查映射中的級聯,並將更新保持在最低限度。