Home > Enterprise >  Validate services created before start a new one or rollback if someone fails
Validate services created before start a new one or rollback if someone fails

Time:10-25

Currently, I'm working on an ASP.NET Core 6 MVC application with C#, and I have a POST controller method with multiple service calls; each service saves the info in the database with EF Core using

await _db.SaveChangesAsync();

This is the controller:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(CreateViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    var addressModel = new Address
    {
        AddressLine1 = model.AddressLine1,
        AddressLine2 = model.AddressLine2,
        City = model.City,
        State = model.State,
        ZipCode = model.ZipCode,
        PhoneNumber = model.PhoneNumber,
        FaxNumber = model.FaxNumber,
    };

    var addressResult = await _addressesService.CreateAddressAsync(addressModel);

    var primaryContactModel = new Contact
    {
        FirstName = model.PrimaryContactFirstName,
        LastName = model.PrimaryContactLastName,
        EmailAddress = model.PrimaryContactEmailAddress,
        PhoneNumber = model.PrimaryContactPhoneNumber
    };

    var alternateContactModel = new Contact
    {
        FirstName = model.AlternateContactFirstName,
        LastName = model.AlternateContactLastName,
        EmailAddress = model.AlternateContactEmailAddress,
        PhoneNumber = model.AlternateContactPhoneNumber
    };

    var primaryContactResult = await _contactsService.CreateContactAsync(primaryContactModel);
    var alternateContactResult = await _contactsService.CreateContactAsync(
        alternateContactModel
    );

    var user = await GetCurrentUserAsync();

    var advertiserModel = new Advertiser
    {
        Name = model.Name,
        AddressId = addressResult.AddressId,
        PrimaryContactId = primaryContactResult.ContactId,
        AlternateContactId = alternateContactResult.ContactId,
        IsActive = model.IsActive,
        CreatedById = user.Id
    };

    await _advertisersService.CreateAdvertiserAsync(advertiserModel);

    var message = "The Advertiser was successfully added!";
    TempData["SuccessMessage"] = message;

    return RedirectToAction("Index");
}

As you can see, I have three entities, Advertiser, Contact and Address.

One advertiser can have contact and one address, so the advertiser table has a foreign key to those tables; my question here is, how can I ensure the Address or Contact have been created successfully after the advertiser try to be executed?

And what happens if the advertiser fails? The contact and address have been already created, how can I rollback if the advertiser fails? Regards

CodePudding user response:

From your description, You have three models in your project, When creating these three models, If any one of these models fails to be created, the entire project will be rolled back, So I think you can use EF Core Transactions. Actually, The SaveChanges() method itself is a transaction, but if multiple SaveChanges() methods are submitted, IDbContextTransaction is required.You can try this code:

        IDbContextTransaction tran = null;
        try
        {
            tran = _myDbContext.Database.BeginTransaction();

             //.... create model.....
          
            tran.Commit();
        }
        catch(Exception ex)
        {
            if(tran !=null)
            {
                tran.Rollback();
            }
        }
        finally
        {
            if(tran !=null)
            {
              tran.Dispose();
            }
        }

Or

using (DbContextTransaction transaction = context.Database.BeginTransaction())
    {
        try
        {
            //.......

            transaction.Commit();
        }
        catch (Exception ex)
        {
            transaction.Rollback();
            Console.WriteLine("Error occurred.");
        }
    }

You can learn more in this link;

  • Related