2012-11-02 56 views
1

我想我可能會讓我的工作單元在我的架構中設置錯誤。這裏是我現在有的(縮進顯示順序):NHibernate中的工作單元和每個請求的會話數

HttpRequest.Begin() 
    UnitOfWork.Begin() 
    Session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted); 

在這裏,我打電話給各種服務使用NHibernate執行crud。當我要做出改變的數據庫(更新/保存),我把這段代碼:

 using (var transaction = unitOfWork.Session.BeginTransaction()) 
     { 
      try 
      { 
       // These are just generics 
       ret = (Key)unitOfWork.Session.Save(entity); 
       transaction.Commit(); 
       rb.unitOfWork.Session.Clear(); 
      } 
      catch 
      { 
       transaction.Rollback(); 
       rb.unitOfWork.Session.Clear(); 
       rb.unitOfWork.DiscardSession(); 
       throw; 
      } 
     } 

當的HttpRequest結束後,我執行以下步驟:

 UnitOfWork.Commit() 
    Transaction.Commit() // This is my sessions transaction from the begin above 

我遇到能夠回滾大批量流程的問題。因爲我在我的CRUD層中提交事務,如上所示,我的事務不再處於活動狀態,當我嘗試在我的UnitOfWork中回滾時,由於事務已經提交,它不做任何事情。我在我的CRUD層中提交代碼的原因是,我可以儘可能快地保留數據,而不會將數據庫鎖定時間過長。

採取類似上述情況的最佳行動方案是什麼?我是否只做了特殊的CRUD操作,它不會提交批量作業,只是在作業結束時處理提交,還是我的邏輯只是出現了UnitOfWork和Session Per Request錯誤?有什麼建議麼?

回答

8

你已經發現爲什麼session-per-request模式如此受歡迎,以及微管理你的工作單元可能產生的問題。

通常對於每個Web請求,需要在該請求內完成的所有事情都可以被認爲是一個工作單元,因此您應該只有一個工作單元和一個NHibernate會話,網絡請求。

另外,我想你可能會對NHibernate的工作原理感到困惑,因爲你的問題中有這句話:「我在我的CRUD層中提交代碼的原因是我可以儘可能快地保存數據而不會將數據庫鎖定時間過長。「

NHibernate不會在您的數據庫中造成任何鎖定。每次調用ISession.Save(實體)時,只要不調用ISession.Flush()或ITransaction.Commit(),就不會將任何內容寫入數據庫,而是將其添加到要插入的項目隊列中,或者當Web請求結束時提交當前事務時,在數據庫中進行更新。

所以每個請求您的會話應該建立像這樣:

void Application_BeginRequest() 
{ 
    // Start your unit of work, open a session and begin a transaction 
} 

// Do all of your work (Read, insert, update, delete) 

void Application_EndRequest() 
{ 
    try 
    { 
     // UnitOfWork.Current.Transaction.Commit(); 
    } 
    catch(Exception e) 
    { 
     // UnitOfWork.Current.Transaction.Rollback(); 
    } 
} 

當然也有很多方法可以做到同樣的事情,但是這是每一個--only會話請求模式會話的基礎知識整個Web請求。

+0

迄今爲止找到的最簡單完整的解釋! – Joel

相關問題