Abp之工作单元与事务

环境:Abp1.2

疑问:没有调用工作单元的SaveChanges方法引起的事务提交时机的问题.

例如:有一个应用服务代码如下:

 public void CreatePhrase(PhraseCreateDto input)
        {var phrase = Mapper.Map<Phrase>(input);
                phrase.Id = Guid.NewGuid();
                _phraseRepository.Insert(phrase);
        }

根据用户提交数据插入一条记录,但在方法末未显式调用SaveChanges方法

在Mvc的Controller里调用上述方法的代码如下:

   [AbpAuthorize]
        public ActionResult Create()
        {
            ViewBag.Count = _phraseAppService.GetCount();
            return View();
        }

        [AbpAuthorize]
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Create(FormCollection fc)
        {
            CheckModelState();

            if ((fc.Get("editorValue") != null) && (fc.Get("ChineseMean") != null))
            {
                //ueditor有时会在最后多出一个br换行,需要去掉.
                var sentenceHtml = fc.Get("editorValue");

                var phrase = new PhraseCreateDto
                {
                    ChineseMean = fc.Get("ChineseMean"),
                    SentenceHtml = sentenceHtml,
                    //1.去掉Html标签 2.把单引号,双引号等被转义的字符转回来.
                    Sentence = Server.HtmlDecode(Common.ReplaceHtmlMark(sentenceHtml))
                };
                _phraseAppService.CreatePhrase(phrase);
            }

            return Create();
        }

在_phraseAppService.CreatePhrase(phrase),插入记录之后,再调用无参的Create方法,在Create方法里ViewBag.Count = _phraseAppService.GetCount()得到的记录数,仍然是原来的记录数(并没有+1),也就是说插入数据发生在获取记录数之后,如果在CreatePhrase方法末显式调用当前工作单元的SaveChanges方法,每次就能获得最新的记录数:

        public void CreatePhrase(PhraseCreateDto input)
        {var phrase = Mapper.Map<Phrase>(input);
                phrase.Id = Guid.NewGuid();
                _phraseRepository.Insert(phrase);
            CurrentUnitOfWork.SaveChanges();
    }

还有一点需要注意:工作单元与事务这二者的关系,假如有如下代码:

        public void CreatePhrase(PhraseCreateDto input)
        {
            using (var uow=UnitOfWorkManager.Begin())
            {
                var phrase = Mapper.Map<Phrase>(input);
                phrase.Id = Guid.NewGuid();
                _phraseRepository.Insert(phrase);
                uow.Complete();
            }
            throw new Exception($"the exception inner {nameof(CreatePhrase)}");
        }

在调用UnitOfWorkHanle的Complete之后,抛出一个异常,那么有没有插入数据呢?答案是不一定,因为在应用服务方法里默认的就是一个工作单元,再在方法里面建一个更小范围的工作单元,并不一定会创建一个事务,而有可能使用已经有的事务,而已有的事务归外层的工作单元管理,所以调用Complete方法并不会提交事务,所以抛出异常后,外层的工作单元就会回滚事务.

不过Begin有几个重载,例如:

Required:默认值,如果事务不存在则新建,如果已存在,则用之.

RequiresNew:始终新建事务.所以如果使用:var uow=UnitOfWorkManager.Begin(TransactionScopeOption.RequiresNew),则在抛出异常前提交事务.

Suppress:无需周围事务上下文,工作单元域内的所有操作会被提交.

时间: 2024-10-03 23:02:27

Abp之工作单元与事务的相关文章

&lt;&lt;ABP框架&gt;&gt; 工作单元

文档目录 本节内容: 简介 在ABP中管理连接和事务 约定的工作单元 UnitOfWork 特性 IUnitOfWorkManager 工作单元详情 禁用工作单元 非事务性工作单元 工作单元方法调用另一个方法 工作单元域 自动保存修改 IRepository.GetAll() 方法 UnitOfWork 限制 选项 方法 SaveChanges 事件 简介 在一个使用数据库的应用里,连接和事务是非常重要的,何时打开一个连接,何时开启一个事务,如果释放连接等等.ABP通过工作单元系统管理数据库的连

手工搭建基于ABP的框架 - 工作单元以及事务管理

一个业务功能往往不只由一次数据库请求(或者服务调用)实现.为了功能的完整性,我们希望如果该功能执行一半时出错,则撤销前面已执行的改动.在数据库层面上,事务管理实现了这种完整性需求.在ABP中,一个完整的业务功能称为一个工作单元(Unit of Work,简称UoW).工作单元代表一种完整的.原子性的操作.即一个工作单元包含的步骤要么全部被执行,要么都不被执行.如果执行一半时出现异常,则必须讲已执行的步骤还原.通常我们将事务管理实现在工作单元中.下面我们从ABP源码入手研究如何使用工作单元. AB

ABP官方文档翻译 3.6 工作单元

工作单元 介绍 ABP中的连接和事务管理 传统的工作单元方法 控制工作单元 UnitOfWork特性 IUnitOfWorkManager 工作单元详情 禁用工作单元 无事务工作单元 一个工作单元方法调用另一个 工作单元范围 自动保存更改 IRepository.GetAll()方法 工作单元特性限制 选项 方法 SaveChanges 事件 介绍 在使用数据库的应用中,连接和事务管理是最重要的概念之一.什么时候打开连接,什么时候开始一个事务,如何释放连接等等.ABP使用工作单元系统来管理连接和

基于DDD的.NET开发框架 - ABP工作单元(Unit of Work)

返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WEB应用程序框架和项目模板. ABP的官方网站:http://www.aspnetboilerplate.com ABP官方文档:http://www.aspnetboilerplate.com/Pages/Documents Github上的开源项目:http

【.Net设计模式系列】工作单元(Unit Of Work)模式 ( 二 )

回顾 在上一篇博客[.Net设计模式系列]仓储(Repository)模式 ( 一 ) 中,通过各位兄台的评论中,可以看出在设计上还有很多的问题,在这里特别感谢 @横竖都溢 @ 浮云飞梦 2位兄台对博文中存在的问题给予指出,并提供出好的解决方案,同时也感谢其他园友的支持.欢迎各位园友对博文中出现的错误或者是设计误区给予指出,一方面防止“误人子弟”,另一方面则可以让大家共同成长. 对于上一篇博客,只是给大家提供了一种对于小型项目数据访问层的一种实现方式,通过Sql语句和传递参数来实现CRUD.并未

应用程序框架实战十九:工作单元层超类型

上一篇介绍了DDD聚合以及与并发相关的各种锁机制,本文将介绍另一个核心元素——工作单元,它是实现仓储的基础. 什么是工作单元 维护受业务事务影响的对象列表,并协调变化的写入和并发问题的解决. 这是<企业应用架构模式>中给出的定义,不过看上去有点抽象.它大概的意思是说,对多个操作进行打包,记录对象上的所有变化,并在最后提交时一次性将所有变化通过系统事务写入数据库. 当然,工作单元不一定是针对数据库的,不过大部分程序员还是工作在关系数据库中,所以我默认你也在使用关系数据库,由此产生的不准确性你就不

工作单元(Unit Of Work)模式 ( 二 )

转自 http://www.cnblogs.com/retop/p/5193394.html 理论介绍 在进行数据库添加.修改.删除时,为了保证事务的一致性,即操作要么全部成功,要么全部失败.例如银行A.B两个账户的转账业务.一方失败都会导致事务的不完整性,从而事务回滚.而工作单元模式可以跟踪事务,在操作完成时对事务进行统一提交. 理论参考:http://martinfowler.com/eaaCatalog/unitOfWork.html 具体实践 首先,讲解下设计思想:领域层通过相应的库实现

换个角度说工作单元(Unit Of Work):创建、持有与API调用

看到一些工作单元的介绍,有两种感觉,第一种是很学院,说了等于没说,我估计很多都是没有自己引入到实际的项目中去,第二种是告诉我一种结果,说这就是工作单元,但是没说为什么要这么使用.所以,本篇想要探讨的是:为什么工作单元要这么用.首先,要想将工作单元引入到自己的项目中去,急需要解决的一个问题是:工作单元的生命周期,即: 1:工作单元被谁创建,何时消亡? 2:工作单元被谁们持有? 3:工作单元的 4 个 API( MakeNew.MakeDirty.MakeRemoved.Commit )被谁调用?

工作单元 — Unit Of Work

在进行数据库添加.修改.删除时,为了保证事务的一致性,即操作要么全部成功,要么全部失败.例如银行A.B两个账户的转账业务.一方失败都会导致事务的不完整性,从而事务回滚.而工作单元模式可以跟踪事务,在操作完成时对事务进行统一提交. 具体实践 首先,讲解下设计思想:领域层通过相应的库实现泛型仓储接口来持久化聚合类,之后在抽象库中将对泛型仓储接口提供基础实现,并将对应的实体转化为SQl语句.这样领域层就不需要操作Sql语句即可完成CRUD操作,同时使用工作单元对事务进行统一提交. 1)定义仓储接口,包