NHibernate之旅(6):探索NHibernate中的事务

本节内容

事务概述1.新建对象【测试成功提交】【测试失败回滚】

上一篇我们介绍了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之旅(6):探索NHibernate中的事务

相关文章:

你感兴趣的文章:

标签云: