0

I have a created an Entity Framework 6 transaction and I update some data inside of it, then an exception is being thrown by some code. I catch the exception and rollback the transaction. However, when I check the database I see that the data has been updated even though I rolled back the transaction.

How can I prevent data from being saved when an exception happens?

 public void MainMethod(){
        try {
           MethodA();
        }
        catch (Exception) {
             using (var tran = _context.Database.BeginTransaction())
            {
               try
               { 
                   var logObject = new LogObject();
                   logObject.text = "some text";
                  _context.LogObjects.Add(logObject);
                   _context.SaveChanges();
                  tran.Commit();//when an exception happens in MethodA, the method a data still saves, when this transaction gets committed here.
               }
               catch (Exception)
               {
                  tran.Rollback();
                  throw;
               }
           }
        }
    }

    public void MethodA()
    {
        using (var tran = _context.Database.BeginTransaction())
        {
            try
            {
                UpdateMyData();
                _context.SaveChanges();
                tran.Commit();
                tran.Dispose();
            }
            catch (Exception)
            {
                tran.Rollback();
                tran.Dispose();
                throw;
            }
        }
    }

    public void UpdateMyData()
    {
        try
        {
            var dataRecord = _context.MySampleDataRecords.Where(x => x.isActive).First();
            dataRecord.isActive = false;  //This update is being saved to the database and it should not be saved
        }
        catch (Exception ex)
        {
            throw new Exception("Test exception");
        }
    }
AAV
  • 373
  • 1
  • 5
  • 17
  • Does this answer your question? [Entity Framework 6 transaction rollback](https://stackoverflow.com/questions/22486489/entity-framework-6-transaction-rollback) – Roar S. Dec 08 '20 at 18:18
  • @Roar Unfortunately it does not. According to that explanation the dataRecord.isActive = false from my code should not be saved to the database, but for some reason it is being saved. – AAV Dec 08 '20 at 19:00
  • Are you sure `Db` and `_context` refer to same DbContext? In any case simply and try to post a complete repro of the issue. You'll probably find your issue yourself, if not, post the repro. – David Browne - Microsoft Dec 08 '20 at 19:06
  • @DavidBrowne-Microsoft Yes, they are the same context, I have even updated the code to use the same for clarity. It turn out that my change from MethodA is being committed on a transaction in the MainMethod. I have tried calling Dispose on MethodA, but the issue continues. – AAV Dec 08 '20 at 20:05
  • I used the following answer to solve my problem. Detached my entity from the context: https://stackoverflow.com/a/33901817/618916 – AAV Dec 08 '20 at 20:56
  • Yes. The rollback does not clear the change tracker, so if you want to continue to use the DbContext after the rollback, and you don't want to retry the SaveChanges(), you must clear the change tracker. – David Browne - Microsoft Dec 09 '20 at 00:38

1 Answers1

0

you need to use same db context for starting the transaction scope and editing data context. also you must rollback the changes on failure

       public void MethodA()
        {
            using (var tran = _context.Database.BeginTransaction())
            {
                try
                {
                    UpdateMyData();
                    Db.SaveChanges();
                    tran.Commit();
                }
                catch (Exception)
                {
                    tran.Rollback();
                    throw;
                }
            }
        }

        public void UpdateMyData()
        {
            try
            {
                var dataRecord = _context.MySampleDataRecords.Where(x => x.isActive).First();
                dataRecord.isActive = false;  //This update is being saved to the database and it should not be saved
            }
            catch (Exception ex)
            {
                _context.Rollback();
                throw new Exception("Test exception");
            }
        }
coder_b
  • 827
  • 6
  • 15
  • I accidently posted an edit to your answer. I was trying to edit my own question. – AAV Dec 08 '20 at 19:58