2012-08-25 39 views
1

我使用NHibernate與甲骨文,我讓NHibernate句柄獲取我的表主鍵的下一個序列值。在下面的代碼中,我似乎無法讓NHibernate在第二次調用transaction.Commit()時保存我的對象。數據庫表ReportSource已經有一個Name列設置爲「test2」的記錄,並且我在Name列上設置了一個唯一的約束。所以我期望第一個transaction.Commit()失敗。但爲什麼它是第二個transaction.Commit()失敗後,我已經更新ReportSource對象的名稱不在數據庫中?NHibernate不會保存我的對象,如果它是以前失敗的事務的一部分

 using (var session = Ioc.Container.Get<ISession>()) 
     { 
      var db = new ReportSource { Name = "test2", ConnectionString = "test", Provider = "test" }; 
      using (var transaction = session.BeginTransaction()) 
      { 
       try 
       { 
        session.SaveOrUpdate(db); 
        transaction.Commit(); 
       } 
       catch (Exception ex) 
       { 
        transaction.Rollback(); 
       } 
      } 
      using (var transaction = session.BeginTransaction()) 
      { 
       try 
       { 
        db.Name = "test4"; 
        //fails with or without the below statement 
        //session.SaveOrUpdate(db); 
        transaction.Commit(); 
       } 
       catch (Exception ex) 
       { 
        transaction.Rollback(); 
       } 
      } 
     } 

回答

2

如果數據庫在通話過程中發生異常時,你不應該嘗試做相同的會話中其他任何東西。相反,當前會話應該被丟棄,因爲它不再處於一致狀態。這就是NHibernate的文檔pointing out

如果ISession的拋出一個異常,你應該立即回滾 的交易,稱之爲ISession.Close()和丟棄的ISession 實例。 ISession的某些方法不會使會話保持一致的狀態。

而不是嘗試在同一個會話中進行另一個事務,您應該創建另一個會話並重試。

using (var session = Ioc.Container.Get<ISession>()) 
{ 
    var db = new ReportSource { 
     Name = "test2", ConnectionString = "test", Provider = "test" }; 
    using (var transaction = session.BeginTransaction()) 
    { 
     try 
     { 
      session.SaveOrUpdate(db); 
      transaction.Commit(); 
     } 
     catch (Exception ex) 
     { 
      transaction.Rollback(); 
     } 
    } 
} 
using (var session = Ioc.Container.Get<ISession>()) 
{ 
    using (var transaction = session.BeginTransaction()) 
    { 
     try 
     { 
      // assign to the new session 
      session.Update(db); 
      db.Name = "test4"; 
      session.SaveOrUpdate(db); 
      transaction.Commit(); 
     } 
     catch (Exception ex) 
     { 
      transaction.Rollback(); 
     } 
    } 
} 
相關問題