2014-12-04 34 views
0

我跑進了「問題」,我是經常重複使用現在/ copy'n'pasting來檢查,如果一個NHibernate的的Isession目前處於交易,如果不開始一個代碼。將數據庫代碼與委託進行交易的一般方法?

現在,我認爲這將是很好,如果我只是做了一個實用工具類的靜態方法,我可以用的Isession對象,幷包含實際的數據庫代碼的委託提供,然後只使用該方法來封裝如果還沒有一個正在進行的交易中的東西。

所以這就是我想出的。

public static class TransactionUtils 
{ 
    public static void EncloseInTransaction(ISession session, Action<ISession> codeToEnclose) 
    { 
     if (session == null) 
      throw new ArgumentNullException("session"); 

     var isInTrans = session.Transaction != null && session.Transaction.IsActive; 

     var tx = isInTrans ? session.Transaction : session.BeginTransaction(); 

     try 
     { 
      codeToEnclose(session); 

      if (!isInTrans) 
       tx.Commit(); 
     } 
     catch (Exception e) 
     { 
      tx.Rollback(); 
      throw; 
     } 
     finally 
     { 
      if (!isInTrans) 
       tx.Dispose(); 
     } 

    } 
} 

所以這一切都很好,我想。但使用該代碼看起來像這樣。

TransactionUtils.EncloseInTransaction(session, session1 => 
{ 
    session1.Query<Blahblah>().Where(x.Blub == "meh").ToList(); 
    session1.CreateQuery("update Foo set Urgs=:Moo where Id=:Id") 
     .SetParameter("moo", "baaahh") 
     .SetParameter("Id", 12305) 
     .ExecuteUpdate(); 
}); 

我真的不喜歡的(會話,會話1 => ...)這裏一部分。看起來混亂的地獄,有人可以只使用傳遞給委託的代碼裏面會議而不是會話1

所以基本上我的問題是。它實際上是一個問題,如果我拋棄了Action<ISession>且僅Action代替它,然後只用裏面的代碼會議?我知道有很多神奇的發生。但我明白,如果我引用的代表代碼中會議編譯器提供一個指向裏面就有了會議對象。或者其他什麼。我基本上可以使用它。

+0

不能直接回答你的追求離子,但在你的例子中,顯式使用會話沒有意義,單個更新語句隱式地是事務性的,它將工作或失敗。希望你在現實世界中不會像這樣使用它,但我多次見過這種模式。 – 2014-12-04 10:06:59

+0

是的,這個例子非常簡單。但處理隱式事務。我正在使用NHibernate Profiler,並且它始終將事務的隱式使用標記爲可能的性能問題。所以我試圖避免這一點。 – 2014-12-04 10:10:32

回答

1

可以作出這樣的方法擴展方法,這應該使代碼看起來更美觀。

public static void EncloseInTransaction(this ISession session, Action<ISession> codeToEnclose) 

並調用方法:

session.EncloseInTransaction(s => 
{ 
    s.Query<Blahblah>().Where(x.Blub == "meh").ToList(); 
    s.CreateQuery("update Foo set Urgs=:Moo where Id=:Id") 
     .SetParameter("moo", "baaahh") 
     .SetParameter("Id", 12305) 
     .ExecuteUpdate(); 
}); 

您也可以使用Action像你說的(這是確定),它是這樣的:

public static void EncloseInTransaction(this ISession session, Action codeToEnclose) 

調用方法:

session.EncloseInTransaction(() => 
{ 
    session.Query<Blahblah>().Where(x.Blub == "meh").ToList(); 
    session.CreateQuery("update Foo set Urgs=:Moo where Id=:Id") 
     .SetParameter("moo", "baaahh") 
     .SetParameter("Id", 12305) 
     .ExecuteUpdate(); 
}); 
+0

該死的......是啊!爲什麼我沒有想到...非常感謝。 – 2014-12-04 10:05:11

+0

太棒了,歡迎您將問題標記爲已回答:) – 2014-12-04 10:07:17

+0

我會盡快允許我。並感謝您進一步澄清。 – 2014-12-04 10:09:17