Abp之工做單元與事務

 

環境:Abp1.2app

疑問:沒有調用工做單元的SaveChanges方法引發的事務提交時機的問題.ui

例如:有一個應用服務代碼以下:spa

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

根據用戶提交數據插入一條記錄,但在方法末未顯式調用SaveChanges方法code

在Mvc的Controller裏調用上述方法的代碼以下:orm

   [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方法,每次就能得到最新的記錄數:blog

        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方法並不會提交事務,因此拋出異常後,外層的工做單元就會回滾事務.input

不過Begin有幾個重載,例如:it

Required:默認值,若是事務不存在則新建,若是已存在,則用之.io

RequiresNew:始終新建事務.因此若是使用:var uow=UnitOfWorkManager.Begin(TransactionScopeOption.RequiresNew),則在拋出異常前提交事務.

Suppress:抑制外界的事務,工做單元域內的全部操做會被提交.

相關文章
相關標籤/搜索