1

I am using EF6 in my asp.net application. In some code block i am using Transaction Scope. Following is my code

 using (VerbaTrackEntities dataContext = new VerbaTrackEntities())
        {
            TBL_TARGET target = dataContext.TBL_TARGET.Where(x => x.LNG_TARGET_ID == TargetID).SingleOrDefault();
            if (target != null)
            {
                using (var trans = dataContext.Database.BeginTransaction())
                {
                    try
                    {
                        System.Data.Entity.Core.Objects.ObjectContext oc = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)dataContext).ObjectContext;
                        foreach (var Targets in target.TBL_CASE_TARGET.ToList())
                        {
                            oc.DeleteObject(Targets);
                        }
                        foreach (var Targets in target.TBL_USER_TARGET.ToList())
                        {
                            oc.DeleteObject(Targets);
                        }
                        foreach (var Targets in target.TBL_FENCE_TARGET.ToList())
                        {
                            oc.DeleteObject(Targets);
                        }
                        foreach (var Targets in target.TBL_TARGET_COMM.ToList())
                        {
                            oc.DeleteObject(Targets);
                        }
                        foreach (var Targets in target.TBL_TRG_FENCE_STATUS.ToList())
                        {
                            oc.DeleteObject(Targets);
                        }
                        foreach (var Targets in target.TBL_TRG_MOVEMENT.ToList())
                        {
                            oc.DeleteObject(Targets);
                        }
                        TBL_IMAGE deleteImage = dataContext.TBL_IMAGE.Where(s => s.LNG_REF_ID == target.LNG_TARGET_ID && s.INT_TYPE_OF_IMAGE == 2).SingleOrDefault();
                        if (deleteImage != null)
                            oc.DeleteObject(deleteImage);
                        oc.SaveChanges();
                        dataContext.TBL_TARGET.Remove(target);
                        TargetEditForm.UpdateTargetSession(target, 1);
                        trans.Commit();
                        return dataContext.SaveChanges();
                    }
                    catch
                    {
                        trans.Rollback();
                        return 0;
                    }
                }
            }
        }

The following code when fails on trans.Commit();. It goes in catch block for executing trans.Rollback. Here it throws exception Underlying data cannot be rollback. On debug i found that trans.Connection is null. What is correct way to rollback from here ..

Rajeev Kumar
  • 4,901
  • 8
  • 48
  • 83
  • Catch the original exeption message before rollback exception, and post it. – Marc Cals Jun 11 '15 at 12:01
  • Exception was due to foreign key reference remain in some table before deleting main table – Rajeev Kumar Jun 11 '15 at 12:08
  • I know the problem but my question was in case exception throws in try block then why it is not rollback in catch block. why `trans.connection` set to null in catch block – Rajeev Kumar Jun 11 '15 at 12:12
  • possible duplicate of [SqlTransaction after catch transaction connection is null](http://stackoverflow.com/questions/9839631/sqltransaction-after-catch-transaction-connection-is-null) – Marc Cals Jun 11 '15 at 12:17
  • 3
    Honestly, I would not return and call `SaveChanges` on the same line, I would do `var result = dataContext.SaveChanges(); trans.Commit(); return result;`. This lets the save be inside the transaction. – Scott Chamberlain Jun 11 '15 at 13:13

1 Answers1

5

The trans.Rollback on the catch is not necessary, because the transaction is inside using. When Disposable() from transaction is called, it does automatically a rollback.

Marc Cals
  • 2,963
  • 4
  • 30
  • 48
  • Does it really !!! But in my case it is not rollback. May be due to i m using OjbectContext to delete the rows from referenced tables ? What could be the solution in my case – Rajeev Kumar Jun 12 '15 at 07:12
  • Sorry, I have never work with ObjectContext directly. But for me it doesn't make sense, DataContext is simply a wrapper of ObjectContext, Thinking logically it seems that they have to share the same connection and transaction scope. If I were you I'll check if the two objects share the same database connection – Marc Cals Jun 12 '15 at 07:34
  • @MarcCals, in this case, is it needed to use the try-catch statement? Since on catch I am only calling transaction.Rollback() and rethrow the exception. – Marian Simonca Jun 06 '19 at 11:45