標籤:blog http io 使用 ar strong for 資料 cti
本節內容
- 事務概述
- 1.建立對象
- 2.刪除對象
- 3.更新對象
- 4.儲存更新對象
- 結語
上一篇我們介紹了NHibernate中的Insert, Update, Delete操作,這篇我們來看看NHibernate中的事務。你通過它可以提交或者復原你的操作。
事務概述1.NHibernate中的事務(Transactions)
簡單描述:要求ISession使用事務;做一些操作;提交或者復原事務。
寫成代碼就像這樣:
ITransaction tx = _session.BeginTransaction();//一些儲存、更新、刪除等操作tx.Commit();
實際上在NHibernate使用事務要使用using強制資源清理和異常機制,一般像這樣:
using (ITransaction tx = _session.BeginTransaction()){ try { //一些儲存、更新、刪除等操作 tx.Commit(); } catch (HibernateException) { tx.Rollback(); throw; }}
2.什麼時候使用事務?
回答是:在任何時候都要使用事務,即使是在讀取、查詢資料的時候,為什麼呢?因為你不清楚資料庫什麼時候操作失敗,如何恢複原來資料。而NHibernate中的事務(可以通過 tx.Rollback()方法),協助我們完成這些事情。
下面看看例子,我們修改上篇的Insert、Update、Delete操作:
1.建立對象
public int CreateCustomerTransaction(Customer customer){ using (ITransaction tx = _session.BeginTransaction()) { try { int newId = (int)_session.Save(customer); _session.Flush(); tx.Commit(); return newId; } catch (HibernateException) { tx.Rollback(); throw; } }}
這篇以建立對象為例,分別從成功提交和失敗復原兩個角度來測試這個方法。
【測試成功提交】
首先寫一個測試案例,假設這個測試可以運行成功:
[Test]public void CreateCustomerTransactionTest(){ var customer = new Customer() { Firstname = "YJing", Lastname = "Lee" }; int newIdentity = _transaction.CreateCustomerTransaction(customer); var testCustomer = _transaction.GetCustomerById(newIdentity); Assert.IsNotNull(testCustomer);}
測試這個方法,使用TestDriven.NET整合的NCover(分析代碼的覆蓋率)查看代碼運行覆蓋率,在這個測試方法上右擊選擇“Test With”—“Coverage”,如所示:
這時自動開啟NCoverExplorer(查看程式碼涵蓋範圍的分析結果),我們可以看到CreateCustomerTransaction方法運行覆蓋情況,我們發現這個方法通過事務成功提交了操作並返回新的Id。分析結果如下所示:
【測試失敗復原】
我們在寫一個失敗復原的測試,由於我認為設定了一個“將截斷字串或位元據”錯誤,這時必須在測試方法上指定測試預期的異常。
[Test][ExpectedException(typeof(NHibernate.HibernateException))]public void CreateCustomerThrowExceptionOnFailTest(){ var customer = new Customer() { Firstname = "012345678901234567890123456789012345678901234567890123456789", Lastname = "YJingLee" }; _transaction.CreateCustomerTransaction(customer);}
同理按上面的步驟測試這個方法看看CreateCustomerTransaction方法運行情況,由於出現錯誤(這裡是“將截斷字串或位元據”錯誤),所以系統拋出了HibernateException異常,此時系統發生復原。分析結果如下所示:
2.刪除對象
我們修改上例中的刪除對象的代碼,如下所示:
public void DeleteCustomerTransaction(Customer customer){ using (ITransaction tx = _session.BeginTransaction()) { try { _session.Delete(customer); _session.Flush(); tx.Commit(); } catch (HibernateException) { tx.Rollback(); throw; } }}
3.更新對象
我們修改上例中的更新對象的代碼,如下所示:
public void UpdateCustomerTransaction(Customer customer){ using (ITransaction tx = _session.BeginTransaction()) { try { _session.Update(customer); _session.Flush(); tx.Commit(); } catch (HibernateException) { tx.Rollback(); throw; } }}
4.儲存更新對象
我們修改上例中的儲存更新對象的代碼,如下所示:
public void SaveOrUpdateCustomersTransaction(IList<Customer> customers){ using (ITransaction tx = _session.BeginTransaction()) { try { foreach (Customer c in customers) _session.SaveOrUpdate(c); _session.Flush(); tx.Commit(); } catch (HibernateException) { tx.Rollback(); throw; } }}
好了,由於篇幅有限,上面三個方法在這裡我就不測試了,大家可以參考建立對象測試的步驟來測試一下其他幾個方法吧!
結語
感覺這節內容很少的樣子,在NHibernate官方文檔中對事務講解的並不多,自己挖空心思也就擠了這麼多東西。不過在這一節帶領大家學會了測試載入器TestDriven.NET的另一個功能就是怎麼查看代碼運行覆蓋率,還是有一點收穫的哦。下一節想繼續深入事務話題一起討論NHibernate中的並發控制,到現在還沒有想好怎麼寫呢,希望大家對這個系列給出意見和建議。謝謝支援!
[轉]NHibernate之旅(6):探索NHibernate中的事務