using (ITransaction tx = _session.BeginTransaction())
{
try
{
//一些保存、更新、删除等操作
tx.Commit();
}
catch (HibernateException)
{
tx.Rollback();
throw;
}
}
2.什么时候使用事务?
回答是:在任何时候都要使用事务,即使是在读取、查询数据的时候,为什么呢?
因为你不清楚数据库什么时候操作失败,如何恢复原来数据。
而NHibernate中的事务(可以通过 tx.Rollback()方法),帮助我们完成这些事情。
写一个测试用例,假设这个测试可以运行成功:
[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的另一个功能就是怎么查看代码运行覆盖率,