Entity Framework 6 Transaction Rollback

Entity Framework 6 transaction rollback

You don't need to call Rollback manually because you are using the using statement.

DbContextTransaction.Dispose method will be called in the end of the using block. And it will automatically rollback the transaction if the transaction is not successfully committed (not called or encountered exceptions). Following is the source code of SqlInternalTransaction.Dispose method (DbContextTransaction.Dispose will finally delegate to it when using SqlServer provider):

private void Dispose(bool disposing)
{
// ...
if (disposing && this._innerConnection != null)
{
this._disposing = true;
this.Rollback();
}
}

You see, it checks if _innerConnection is not null, if not, rollback the transaction (if committed, _innerConnection will be null). Let's see what Commit does:

internal void Commit() 
{
// Ignore many details here...

this._innerConnection.ExecuteTransaction(...);

if (!this.IsZombied && !this._innerConnection.IsYukonOrNewer)
{
// Zombie() method will set _innerConnection to null
this.Zombie();
}
else
{
this.ZombieParent();
}

// Ignore many details here...
}

internal void Zombie()
{
this.ZombieParent();

SqlInternalConnection innerConnection = this._innerConnection;

// Set the _innerConnection to null
this._innerConnection = null;

if (innerConnection != null)
{
innerConnection.DisconnectTransaction(this);
}
}

Rollback on Entity Framework 6

Nothing will happen to the context.You can use it even after the rolled back.Only the database changes will be rolled back and the DbContextTransaction is meant to be disposed once it has been committed or rolled back.

You can use EF 6's latest transaction API as shown below.

using (var context = new YourContext()) 
{
using (var dbContextTransaction = context.Database.BeginTransaction())
{
try
{
//your db operations

context.SaveChanges();

dbContextTransaction.Commit();
}
catch (Exception)
{
dbContextTransaction.Rollback();
}
}
}

You can read more about it here : Entity Framework Working with Transactions

EF6 Transaction Rollback

Have your models that require syncing to implement an interface, iSyncable for example, that promises that you will sync up as soon as the model successfully saves. If you have related tables through navigation properties, save everything and put those into the navigation properties before you make it sync up so that your syncing function has all the objects it needs.

Incidentally, if you need to do any data transforms, this would be where you do it.

Entity Framework Rollback

You can use code transactions, instead of database transactions. And using using statements to dispose of dbcontext.

using (TransactionScope scope = new TransactionScope())
{
using (MyDBContext db = new MyDBContext())
{
//...
db.SaveChanges()
}
scope.Complete();
}

using (MyDBContext db = new MyDBContext())
{
//...
db.SaveChanges()
}
scope.Complete();
}

/* end of adding transaction scope*/
}

EF6. Save exception information to database after rollback transaction

As I understand it, the context in this stage is in a dirty state?

Correct. The "database error" must have occurred in a SaveChanges(Async) call, so if you repeat that call on the same context, the exception will occur again. The remedy is simple: use a new context in the catch block.

Side note: catching the exception in the using block isn't necessary. If the transaction isn't committed before it's disposed, it will be rolled back.

Entity framework 6 transaction

Code can be improved with implicit transaction:

foreach (var item in itemList)
{
context.MyFirstEntity.Add(item);
mySecondEntity.MyFirstEntity = item;
context.MySecondEntity.Add(mySecondEntity);
}
context.SaveChanges();

Note: instead of id I've used navigation property.



Related Topics



Leave a reply



Submit