Base solution for your next web application
Open Closed

Unit of work rollback changes manually when use try catch #529


User avatar
0
mhdbaz created

When I use application service inside a try catch in the controller even if the app service method throw an exception the unit of work commit changes to the DB because I am using try catch block for example

[HttpPost]
        [UnitOfWork]
        //[ValidateAntiForgeryToken()]
        public virtual async Task<ActionResult> Register(SignUpUserInput model)
        {
            var ttt = _unitOfWorkManager.Current;
            //await _userAppService.SignUpUser(model);
            //throw new UserFriendlyException("Test UI Exception");
            try
            {
                CheckModelState();
                //var validateCaptchaResult = ValidateCaptcha();
                //if (!validateCaptchaResult.Succeeded)
                //{
                //    throw new Exception(validateCaptchaResult.Errors.FirstOrDefault() ??  string.Empty);
                //}
                await _userAppService.SignUpUser(model);
                return RedirectToAction("RegistrationCompleted");
            }
            catch (Exception ex)
            {
                ViewBag.ErrorMessage = ex.Message;
                if (ex.InnerException != null)
                {
                    ViewBag.ErrorMessage += "<br>" + ex.InnerException.Message;
                }
                return View(model);
            }
        }

The above code even if _userAppService.SignUpUser(model) throw an exception the unit of work will commit the changes. If I removed the try catch the unit if work rollback the changes. Is there is any way to rollabck the changes manually ?


1 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Your situation is interesting and not fits to purpose of UnitOfWork attrbiute.

    This may work:

    ((IDisposable)CurrentUnitOfWork).Dispose();
    

    in the catch. But I'm not sure and this is not a good practice. Instead, I suggest 2 options:

    • Use UnitOfWorkManager.Begin() / Complete() manually (like <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#iunitofworkmanager">http://www.aspnetboilerplate.com/Pages/ ... orkmanager</a>) inside try block. So, if you throw exception before Complete, it's rolled back automatically.

    • Extract inside of try block to another protected virtual (why protected virtual? <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#DocUowRestrictions">http://www.aspnetboilerplate.com/Pages/ ... strictions</a>) method, make it UnitOfWork and remove UnitOfWork attribute from the main controller action.