B.Balamanigandan
B.Balamanigandan

Reputation: 4875

Entity Framework - Issues in DbContextTransaction.Rollback()

I connected the database using Entity Framework. I Implemented a Contact Repository to Save the Contact Information (Sample Repository). In the Said Class file, I declared a static property for handling DBEntities (i.e., BLabsEntities) namely "Context" and also declared a static property for DbContextTransaction.

In the following code I added a try catch block to handle Exceptions of Entity Framework in the SaveContact() Repository method. I Initiated a transaction before starting the Save Contact process in the above said method, then I added a exceptional data into the database table dbo.Contact as per my thought it thrown the exception. In the Catch block I'm initiating the Rollback process of the said transaction and I'm trying to insert the Exception message in the ErrorLog Table, but the Context property holds the Contact information even-though the Rollback process executed. So, it throwing Exception in the catch block once again while on trying to insert the record in the dbo.ErrorLog Table. I added a debugging snapshot for your reference.

C# Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace EF_Sample
{
    public class ContactRepository
    {
        private static BLabsEntities _context;
        private static DbContextTransaction _dbTransaction;

        protected static BLabsEntities Context
        {
            get { return _context ?? (_context = new BLabsEntities()); }
        }

        protected static DbContextTransaction DBTransaction
        {
            get { return _dbTransaction; }
            set { _dbTransaction = value; }
        }

        public void SaveContact(Contact contact = null)
        {
            try
            {
                if (contact == null)
                {
                    contact = new Contact()
                    {
                        FirstName = null,
                        LastName = null
                    };
                }


                BeginTransaction();
                Context.Contacts.Add(contact);
                Context.SaveChanges();
            }
            catch (Exception ex)
            {
                CommitTransaction(false);

                BeginTransaction();
                ErrorLog error = new ErrorLog()
                {
                    Message = ex.Message
                };

                Context.ErrorLogs.Add(error);

                Context.SaveChanges();
            }
            finally
            {
                CommitTransaction();
            }
        }

        private void BeginTransaction()
        {
            DBTransaction = Context.Database.BeginTransaction();
        }

        private void CommitTransaction(bool flag = true)
        {
            try
            {
                if (flag)
                {
                    DBTransaction.Commit();
                }
                else
                {
                    DBTransaction.Rollback();
                }
            }
            catch (Exception Ex)
            {
                Console.WriteLine("Error: {0}", Ex.Message);
            }
        }
    }
}

Debugging Snapshot:

enter image description here

Exception in try Block: Explicitly Created Exception by Code

enter image description here

Exception in Catch Block: Failure of Rollback operation

enter image description here

Database Table Structures:

enter image description here

Kindly assist me how to do the Rollback operation successfully to clear the Context Changes.

Upvotes: 2

Views: 2517

Answers (1)

Ken
Ken

Reputation: 2808

The actual answer might be more simple:

https://github.com/aspnet/EntityFramework.Docs/issues/327

The explicit call to dbContextTransaction.Rollback() is in most cases unnecessary, because disposing the transaction at the end of the using block will take care of rolling back.

If an error of sufficient severity occurs in SQL Server, the transaction will get automatically rolled back, and the call to dbContextTransaction.Rollback() in the catch block will actually fail.

Upvotes: 4

Related Questions