NHibernate学习教程(6)--事务Transactions

本节内容

  • 事务概述
  • 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中的并发控制,到现在还没有想好怎么写呢,希望大家对这个系列给出意见和建议。谢谢支持!

时间: 2024-08-07 17:17:11

NHibernate学习教程(6)--事务Transactions的相关文章

Nhibernate学习教程(1)-- 开篇有益

NHibernate之旅(1):开篇有益 本节内容 NHibernate是什么 NHibernate的架构 NHibernate资源 欢迎加入NHibernate中文社区 作者注:2009-11-06已更新 NHibernate开篇有益 学习NHibernate有一段时间了,打算做个阶段性总结,就萌生了这个系列,这个系列参考NHibernate官方文档和Steve  Bohlen的NHibernate之夏视频教程.作为开篇,首先了解多少人在使用NHibernate,先搞清楚NHibernate是

Nhibernate学习教程(2)-- 第一个NHibernate程序

NHibernate之旅(2):第一个NHibernate程序 本节内容 开始使用NHibernate 1.获取NHibernate 2.建立数据库表 3.创建C#类库项目 4.设计Domain 4-1.设计持久化类 4-2.编写映射文件 5.数据访问层 5-1.辅助类 5-2.编写操作 6.数据访问层的测试 6-1.配置NHibernate 6-2.测试 结语 开始使用NHibernate 我们亲自动手,一步一步搭建一个NHibernate程序来,我以一个实际场景电子交易程序来模拟,客户/订单

redis学习教程三《发送订阅、事务、连接》

redis学习教程三<发送订阅.事务.连接> 一:发送订阅      Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息.Redis 发布订阅(pub/sub)实现了消息系统,发送者(在redis术语中称为发布者)在接收者(订阅者)接收消息时发送消息.传送消息的链路称为信道. 示例 以下示例说明了发布用户概念的工作原理. 在以下示例中,一个客户端订阅名为"redisChat"的信道. redis 127.0.0.1:6

redis学习教程五《管道、分区》

redis学习教程五<管道.分区> 一:管道 Redis是一个TCP服务器,支持请求/响应协议. 在Redis中,请求通过以下步骤完成: 客户端向服务器发送查询,并从套接字读取,通常以阻塞的方式,用于服务器响应. 服务器处理命令并将响应发送回客户端. 管道的意义 管道的基本含义是,客户端可以向服务器发送多个请求,而不必等待回复,并最终在一个步骤中读取回复. 示例 要检查Redis管道,只需启动Redis实例,并在终端中键入以下命令. (echo -en "PING\r\n SET t

NHibernate学习系列一

NHibernate是一个面向.NET环境的对象/关系数据库映射工具.对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去. 优点: (1)NHibernate不仅仅管理.NET类到数据库表的映射(包括.NET 数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和ADO.NET处理数据的时间. (2)面向对象:NHiberante的使

MySQL数据库开发学习教程

MySQL数据库开发学习教程 一.数据库设计 数据库设计(一)--数据库设计http://blog.51cto.com/9291927/2087925 二.MySQL数据库开发基础教程 MySQL数据库开发基础教程目录如下: MySQL数据库基础(一)--MySQL数据库简介http://blog.51cto.com/9291927/2087947MySQL数据库基础(二)--MySQL字符集与乱码解析http://blog.51cto.com/9291927/2088254MySQL数据库基础

SpringBoot 系列教程之事务隔离级别知识点小结

SpringBoot 系列教程之事务隔离级别知识点小结 上一篇博文介绍了声明式事务@Transactional的简单使用姿势,最文章的最后给出了这个注解的多个属性,本文将着重放在事务隔离级别的知识点上,并通过实例演示不同的事务隔离级别下,脏读.不可重复读.幻读的具体场景 I. 基础知识 在进入正文之前,先介绍一下事务隔离级别的一些基础知识点,详细内容,推荐参考博文 mysql 之锁与事务 1. 基本概念 以下基本概念源于个人理解之后,通过简单的 case 进行描述,如有问题,欢迎拍砖 更新丢失

SpringBoot系列教程之事务传递属性

200202-SpringBoot系列教程之事务传递属性 对于mysql而言,关于事务的主要知识点可能几种在隔离级别上:在Spring体系中,使用事务的时候,还有一个知识点事务的传递属性同样重要,本文将主要介绍7中传递属性的使用场景 I. 配置 本文的case,将使用声明式事务,首先我们创建一个SpringBoot项目,版本为2.2.1.RELEASE,使用mysql作为目标数据库,存储引擎选择Innodb,事务隔离级别为RR 1. 项目配置 在项目pom.xml文件中,加上spring-boo

SpringBoot 系列教程之事务不生效的几种 case

SpringBoot 系列教程之事务不生效的几种 case 前面几篇博文介绍了声明式事务@Transactional的使用姿势,只知道正确的使用姿势可能还不够,还得知道什么场景下不生效,避免采坑.本文将主要介绍让事务不生效的几种 case I. 配置 本文的 case,将使用声明式事务,首先我们创建一个 SpringBoot 项目,版本为2.2.1.RELEASE,使用 mysql 作为目标数据库,存储引擎选择Innodb,事务隔离级别为 RR 1. 项目配置 在项目pom.xml文件中,加上s