2011-11-05 30 views
0

我寫的項目和使用NHibernate 3.1崩潰3.1

SimpleTest的:

 IUserRepository userRepository = new UserRepository(SessionFactory); 
     var admin = userRepository.GetByName("admin"); 
     admin.Profile.Signature = "Signature"; 
     userRepository.Update(admin); 

實施Repository.Update():

public virtual void Update(TEntity entity) 
{ 
    if (!session.Transaction.IsActive) 
    { 
     TResult result; 
     using (var tx = session.BeginTransaction()) 
     { 
      session.SaveOrUpdate(entity) 
      tx.Commit(); 
     } 
     return result; 
    } 
    session.SaveOrUpdate(entity) 
} 

你一定不要混淆調用其他分支中的session.SaveOrUpdate(entity),因爲如果更新在外部事務中調用,則必須調用它。

  • 首先,我收到管理員Version = 1。他的狀態是持久的。
  • 我更改任何屬性的值。
  • 我做更新。
  • 當流量到達線tx.Commit();,NHibernate的生成查詢:

    UPDATE用戶 SET版= 2, 名稱= '管理員', EncryptedPassword = '21232f297a57a5a743894a0e4a801fc3', 使用email =「管理員@管理員.com '之間, IsActivated = 1, IsBanned = 0, CommentsNumber = 0, 角色= '管理', 姓= '阿列克謝', 名字= 'Kovpaev', DATEOFBIRTH =' 1992-01-02T12: 00:00.00', 關於= '只要管理', 簽名= '簽名' 其中userid = 'e23056df-d934-4880-b6b8-f2128cd41504' 和版本= 1

  • NHibernate的拋出異常:NHibernate.StaleObjectStateException:行被更新或者刪除另一個事務(或未保存的值的映射是不正確的)

它也不能正常工作,導致相同的異常:

using (var tx = Session.BeginTransaction()) 
    { 
     var admin = Session.CreateCriteria<User>().Add(Restrictions.Eq("Name", "admin")).UniqueResult<User>(); 
     admin.Profile.Signature = "Signature"; 
     Session.SaveOrUpdate(admin); 
     tx.Commit(); 
    } 

首先,版本號是正確的。其次,其他交易不存在。

爲什麼?

回答

0

我發現有兩個消息來源聲稱NHibernate不支持嵌套事務。建議的解決方案似乎是Ayendes UnitOfWork實現或將您的事務嵌套在TransactionScope中。

How do I do nested transactions in NHibernate?

Achieving NHibernate Nested Transactions Behavior

+0

在這段代碼中,沒有嵌套事務。並且不止一個嵌套級別,因爲它在塊「if」中被檢查。 –

+0

我沒有正確讀取您的代碼。你明確確定沒有嵌套。好。我想知道你的UserRepository。它如何管理會話? GetByName會在內部打開和關閉一個會話,還是保持一個會話在UserRepository的生命週期中打開? – Mithon

+0

這個代碼來自單元測試,並且有一個非常簡單的會話管理。它創建一個會話,並使用它進行所有測試。 在異常會話上升的時刻只有一個持久實體。它是管理員,具有正確的ID和版本。 –