zoukankan      html  css  js  c++  java
  • 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:抑制外界的事务,工作单元域内的所有操作会被提交.

  • 相关阅读:
    WIN7每次从关闭屏幕状态恢复都会挂断宽带连接,请问如何解决?
    程序設計学习之路:不走弯路,就是捷径
    Customize Firefox "Close tab" button
    域名常识
    一到十的英文单词,一十二个月份的英文单词,四季的英文单词,第一,第二第三的英文单词
    Dependency Walker
    刪除當前目錄隱藏文件,非隱藏文件,文件夾等好用的批處理。
    使用 Sandcastle Help File Builder 制作 VS.NET 的 HELP 文件
    字符“23.00”转成int型!Input string was not in a correct format.
    VisualStudio 2010 SP1安装时提示计算机环境导致无法安装的解决办法
  • 原文地址:https://www.cnblogs.com/kid1412/p/6352212.html
Copyright © 2011-2022 走看看