找回密码
 立即注册
首页 业界区 业界 NHibernate之旅(6):探索NHibernate中的事务

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

注思 2025-5-30 01:43:04
本节内容
           
  • 事务概述       
  • 1.新建对象
                     
    • 【测试成功提交】               
    • 【测试失败回滚】       
                   
  • 2.删除对象       
  • 3.更新对象       
  • 4.保存更新对象       
  • 结语
上一篇我们介绍了NHibernate中的Insert, Update, Delete操作,这篇我们来看看NHibernate中的事务。你通过它可以提交或者回滚你的操作。
事务概述

1.NHibernate中的事务(Transactions)

简单描述:要求ISession使用事务;做一些操作;提交或者回滚事务。
写成代码就像这样:
  1. ITransaction tx = _session.BeginTransaction();
  2. //一些保存、更新、删除等操作
  3. tx.Commit();
复制代码
实际上在NHibernate使用事务要使用using强制资源清理和异常机制,一般像这样:
  1. using (ITransaction tx = _session.BeginTransaction())
  2. {
  3.     try
  4.     {
  5.         //一些保存、更新、删除等操作
  6.         tx.Commit();
  7.     }
  8.     catch (HibernateException)
  9.     {
  10.         tx.Rollback();
  11.         throw;
  12.     }
  13. }
复制代码
2.什么时候使用事务?

回答是:在任何时候都要使用事务,即使是在读取、查询数据的时候,为什么呢?因为你不清楚数据库什么时候操作失败,如何恢复原来数据。而NHibernate中的事务(可以通过 tx.Rollback()方法),帮助我们完成这些事情。
下面看看例子,我们修改上篇的Insert、Update、Delete操作:
1.新建对象
  1. public int CreateCustomerTransaction(Customer customer)
  2. {
  3.     using (ITransaction tx = _session.BeginTransaction())
  4.     {
  5.         try
  6.         {
  7.             int newId = (int)_session.Save(customer);
  8.             _session.Flush();
  9.             tx.Commit();
  10.             return newId;
  11.         }
  12.         catch (HibernateException)
  13.         {
  14.             tx.Rollback();
  15.             throw;
  16.         }
  17.     }
  18. }
复制代码
这篇以新建对象为例,分别从成功提交和失败回滚两个角度来测试这个方法。
【测试成功提交】

首先写一个测试用例,假设这个测试可以运行成功:
  1. [Test]
  2. public void CreateCustomerTransactionTest()
  3. {
  4.     var customer = new Customer() { Firstname = "YJing", Lastname = "Lee" };
  5.     int newIdentity = _transaction.CreateCustomerTransaction(customer);
  6.     var testCustomer = _transaction.GetCustomerById(newIdentity);
  7.     Assert.IsNotNull(testCustomer);
  8. }
复制代码
测试这个方法,使用TestDriven.NET集成的NCover(分析代码的覆盖率)查看代码运行覆盖率,在这个测试方法上右击选择“Test With”—“Coverage”,如下图所示:
1.jpeg

这时自动打开NCoverExplorer(查看代码覆盖率的分析结果),我们可以看到CreateCustomerTransaction方法运行覆盖情况,我们发现这个方法通过事务成功提交了操作并返回新的Id。分析结果效果图如下所示:
2.jpeg

【测试失败回滚】

我们在写一个失败回滚的测试,由于我认为设置了一个“将截断字符串或二进制数据”错误,这时必须在测试方法上指定测试预期的异常。
  1. [Test]
  2. [ExpectedException(typeof(NHibernate.HibernateException))]
  3. public void CreateCustomerThrowExceptionOnFailTest()
  4. {
  5.     var customer = new Customer()
  6.     {
  7.         Firstname = "012345678901234567890123456789012345678901234567890123456789",
  8.         Lastname = "YJingLee"
  9.     };
  10.     _transaction.CreateCustomerTransaction(customer);
  11. }
复制代码
同理按上面的步骤测试这个方法看看CreateCustomerTransaction方法运行情况,由于出现错误(这里是“将截断字符串或二进制数据”错误),所以系统抛出了HibernateException异常,此时系统发生回滚。分析结果效果图如下所示:
3.jpeg

2.删除对象

我们修改上例中的删除对象的代码,如下所示:
  1. public void DeleteCustomerTransaction(Customer customer)
  2. {
  3.     using (ITransaction tx = _session.BeginTransaction())
  4.     {
  5.         try
  6.         {
  7.             _session.Delete(customer);
  8.             _session.Flush();
  9.             tx.Commit();
  10.         }
  11.         catch (HibernateException)
  12.         {
  13.             tx.Rollback();
  14.             throw;
  15.         }
  16.     }
  17. }
复制代码
3.更新对象

我们修改上例中的更新对象的代码,如下所示:
  1. public void UpdateCustomerTransaction(Customer customer)
  2. {
  3.     using (ITransaction tx = _session.BeginTransaction())
  4.     {
  5.         try
  6.         {
  7.             _session.Update(customer);
  8.             _session.Flush();
  9.             tx.Commit();
  10.         }
  11.         catch (HibernateException)
  12.         {
  13.             tx.Rollback();
  14.             throw;
  15.         }
  16.     }
  17. }
复制代码
4.保存更新对象

我们修改上例中的保存更新对象的代码,如下所示:
  1. public void SaveOrUpdateCustomersTransaction(IList<Customer> customers)
  2. {
  3.     using (ITransaction tx = _session.BeginTransaction())
  4.     {
  5.         try
  6.         {
  7.             foreach (Customer c in customers)
  8.                 _session.SaveOrUpdate(c);
  9.             _session.Flush();
  10.             tx.Commit();
  11.         }
  12.         catch (HibernateException)
  13.         {
  14.             tx.Rollback();
  15.             throw;
  16.         }
  17.     }
  18. }
复制代码
好了,由于篇幅有限,上面三个方法在这里我就不测试了,大家可以参考创建对象测试的步骤来测试一下其他几个方法吧!
结语

感觉这节内容很少的样子,在NHibernate官方文档中对事务讲解的并不多,自己挖空心思也就挤了这么多东西。不过在这一节带领大家学会了测试工具TestDriven.NET的另一个功能就是怎么查看代码运行覆盖率,还是有一点收获的哦。下一节想继续深入事务话题一起讨论NHibernate中的并发控制,到现在还没有想好怎么写呢,希望大家对这个系列给出意见和建议。谢谢支持!
本系列链接:NHibernate之旅系列文章导航
NHibernate Q&A
           
  • 欢迎加入NHibernate中文社区,一起讨论NHibernate知识!       
  • 请到NHibernate中文社区下载本系列相关源码。
下次继续分享NHibernate!

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册