📚
Hoa Framework
  • 一、框架指南
  • 二、功能特性
  • 三、源码结构
  • 四、代码规范
  • 五、入门指南
  • 六、依赖注入/控制反转
  • 七、控制器和服务
  • 八、对象映射指南
  • 九、数据库操作指南
    • 9.1、正向工程(Code First)
    • 9.2、逆向工程(Database First)
    • 9.3、关于仓储(IRepository)
    • 9.4、增删改操作
    • 9.5、查询操作
    • 9.6、DataSet、DataTable 操作
    • 9.7、查询结果集映射
    • 9.8、批量增删改操作
    • 9.9、存储过程、视图、函数操作
    • 9.10、工作单元和事务
    • 9.11、多上下文、读写分离
    • 9.12、切面上下文(TangentDbContext)
    • 9.13、其他操作
    • 9.14、EF Core 高性能
    • 9.15、常见错误
  • 十、开放接口指南
    • 10.1、RESTFul 和 Swagger
    • 10.2、规范化返回值
  • 十一、数据校验
  • 十二、安全授权
  • 十三、异常处理
  • 十四、日志管理
  • 十五、配置管理
  • 十六、缓存管理
  • 十七、内置工具类
    • 17.1、数据加解密
  • 十八、跨域处理
  • 十九、筛选拦截器(未)
  • 二十、进程服务(Daemon)
  • 二十一、编写测试
    • 20.1、单元测试
    • 20.2、基准测试
    • 20.3、性能测试
  • 二十二、托管部署
    • 22.1、IIS 托管部署
    • 22.2、Nginx 托管部署
    • 22.3、Docker 容器部署
  • 二十三、性能分析(MiniProfiler)
  • 二十四、其他功能
    • 23.1、第三方包管理
    • 23.2、文件上传下载
    • 23.3、Razor 视图引擎
    • 23.4、生成客户端请求代码
    • 23.5、快捷操作
  • 二十五、Docker 容器化
    • 25.1、Docker 介绍
    • 25.2、Docker 安装
    • 25.3、Docker 安装服务
    • 25.4、Docker 常用命令
    • 25.6、Docker run 常用命令
    • 25.7、Docker-Compose 介绍
    • 25.8、docker-compose.yml
    • 25.9、Docker-Compose 常用命令
    • 25.10、Docker-Compose 转换 docker run
    • 25.11、Docker 构建自己的镜像
    • 25.12、Dockerfile指南
    • 25.13、Dockerfile 常用命令
    • 25.14、Dockerfile 打包、上传、分享
    • 25.15、Docker 数据卷
    • 25.16、Docker 域网络
    • 25.17、Docker + Nginx 实现分布式集群、负载均衡
  • 二十六、DevOps 持续部署集成
    • 26.1、DevOps 介绍
    • 26.2、持续集成、交付、部署
    • 26.3、Jenkins 介绍
    • 26.4、Jenkins 安装
    • 26.5、Jenkins 初始化
    • 26.6、Jenkins 实战演练
    • 26.7、Jenkis 项目配置
    • 26.8、Jenkins 插件
  • 二十七、OpenXml/Excel 操作
  • 二十八、SaaS 多租户
  • 二十九、Git 代码管理
    • 29.1、Git 介绍
    • 29.2、Git 安装
    • 29.3、Git 基础配置
    • 29.4、Git 工作流程
    • 29.5、Git 重要概念
    • 29.6、Git 创建仓库
    • 29.7、Git 基本操作
    • 29.8、Git 分支管理
    • 29.9、Git 查看提交历史
    • 29.10、Git 标签
    • 29.11、Git 拉取/获取/推送
    • 28.12、Git GUI工具
    • 29.13、Git 私有化部署
    • 29.14、Git 推荐开发模式
    • 29.15、Svn 转 Git
  • 贡献代码
  • 更新日志
由 GitBook 提供支持
在本页
  • 什么是事务?
  • 事务使用
  • 示例一
  • 示例二
  • 示例三
  • 什么是工作单元
  • 工作单元的使用
  • 工作单元特性参数说明
  • 常见错误
  • 错误一:事务必须在创建的线程上释放

这有帮助吗?

  1. 九、数据库操作指南

9.10、工作单元和事务

数据的完整性和一致性是应用系统不可或缺的功能。

上一页9.9、存储过程、视图、函数操作下一页9.11、多上下文、读写分离

最后更新于4年前

这有帮助吗?

什么是事务?

视图指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。

简单的说,事务就是并发控制的单位,是用户定义的一个操作序列。 而一个逻辑工作单元要成为事务,就必须满足ACID属性。

A:原子性(Atomicity):事务中的操作要么都不做,要么就全做。

C:一致性(Consistency):事务执行的结果必须是从数据库从一个一致性状态转换到另一个一致性状态。

I:隔离性(Isolation):一个事务的执行不能被其他事务干扰

D:持久性(Durability):一个事务一旦提交,它对数据库中数据的改变就应该是永久性的

事务使用

默认情况下,Hoa Framework 每一次请求都开启了分布式事务,保证了每一次请求都是一个完整的 工作单元。

当然,我们也可以手动开启事务,在Hoa Framework 框架中,框架默认的数据库操作ORM: 中的SaveChanges() 已经自动开启了事务。所以很多时候,我们无需手动开启事务。

下面,也给读者展示几个 集中事务示例:

示例一

// 开启事务
using (var transaction = _testRepository.Database.BeginTransaction())
{
    try
    {
        _testRepository.Insert(new Blog { Url = "http://blogs.msdn.com/dotnet" });
        _testRepository.SaveChanges();

        _testRepository.Insert(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
        _testRepository.SaveChanges();

        var blogs = _testRepository.Entity
                .OrderBy(b => b.Url)
                .ToList();

        // 提交事务
        transaction.Commit();
     }
     catch (Exception)
     {
        // 回滚事务
        transaction.RollBack();
     }
}

示例二

var options = new DbContextOptionsBuilder<HoaDbContext>()
    .UseSqlServer(new SqlConnection(connectionString))
    .Options;

// 创建连接字符串
using (var context1 = new HoaDbContext(options))
{
    // 开启事务
    using (var transaction = context1.Database.BeginTransaction())
    {
        try
        {
            _testRepository.Insert(new Blog { Url = "http://blogs.msdn.com/dotnet" });
            _testRepository.SaveChanges();
            
            context1.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
            context1.SaveChanges();

            // 创建新的连接对象
            using (var context2 = new HoaDbContext(options))
            {
                // 共享连接事务
                context2.Database.UseTransaction(transaction.GetDbTransaction());

                var blogs = context2.Blogs
                    .OrderBy(b => b.Url)
                    .ToList();
            }

            // 提交事务
            transaction.Commit();
        }
        catch (Exception)
        {
            // 回滚事务
            transaction.RollBack();
        }
    }
}

示例三

采用分布式事务

// 开启分布式事务
using (var scope = new TransactionScope(
    TransactionScopeOption.Required,
    new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
{
    using (var connection = new SqlConnection(connectionString))
    {
        connection.Open();

        try
        {
            // 这里是 Ado.NET 操作
            var command = connection.CreateCommand();
            command.CommandText = "DELETE FROM dbo.Blogs";
            command.ExecuteNonQuery();

            // 创建EF Core 数据库上下文
            var options = new DbContextOptionsBuilder<BloggingContext>()
                .UseSqlServer(connection)
                .Options;
            using (var context = new BloggingContext(options))
            {
                context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
                context.SaveChanges();
            }
            
            // 框架封装的仓储
            _testRepository.Insert(new Blog { Url = "http://blogs.msdn.com/dotnet" });
            _testRepository.SaveChanges();

           // 提交事务
            scope.Complete();
        }
        catch (System.Exception)
        {
            // 自动回滚
        }
    }
}

什么是工作单元

简单来说,就是为了保证一次完整的功能操作所产生的一些列提交数据的完整性,起着事务的作用。在计算机领域中,工作单元通常用 UnitOfWork 名称表示。

通常我们保证用户的每一次请求都是处于在一个功能单元中,也就是工作单元。

工作单元的使用

默认情况下,在 Hoa Framework 中,工作单元无需我们手动维护,框架会自动保证了每一次请求都是一个 工作单元,要么同时成功,要么同时失败。也就是保证了数据的完整性。

但有些时候,我们出于某种特殊原因,我们不需要保证数据的完整性,也就是无需开启工作单元模式。😢🤢,这时候,我们可以手动关闭工作单元模式,只需要在当前的方法上面贴 [UnitOfWork(false)]即可,如:

[UnitOfWork(false)]
public void IKnowWillThrowExceptionAndInsistHandle(){
    // 执行数据库操作
    // 执行其他操作
    // Oops! 出错了,此时上面的 数据库操作 不会回滚!!!
}

通过上面的例子,我们可得知,如果关闭了工作单元模式,一旦内部出错,所有数据库操作并不会回滚!所以,要慎重使用此特性!🐱‍👤

工作单元特性参数说明

Disabled:禁用工作单元模式,默认 false

IsolationLevel:设置事务隔离级别,默认 IsolationLevel.ReadCommitted;

AsyncFlowOption: 包含数据库异步操作配置选项,默认 TransactionScopeAsyncFlowOption.Suppress,也就是默认不支持异步多线程分布式事务。设置为 TransactionScopeAsyncFlowOption.Enabled 即可启用分布式异步支持。

TransactionScopeOption:定义事务范围行为,默认 TransactionScopeOption.Required

常见错误

错误一:事务必须在创建的线程上释放

A TransactionScope must be disposed on the same thread that it was created.

这时候只需要在方法上贴即可。

[UnitOfWork(AsyncFlowOption = TransactionScopeAsyncFlowOption.Enabled)]

更多事务操作。

EF Core
EF Core
可查官方文档