Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF6 Nested Transactions

I have a command service class, which utilises the unit of work pattern, with various methods to update a database (SQL Azure, in this case) via entity framework.

The command service gets instantiated with a reference to an instance of a dbcontext, whose lifetime is managed by my DI framework of choice.

Some of the command service class' methods wraps multiple updates to the database within a transaction, for example:

public void UpdateStuff(someEntity)
{
    using(var tx = _db.Database.BeginTransaction())
    {
        //Some updates to db
        _db.SaveChanges();
        //Some other updates to db
        _db.SaveChanges();
        tx.Commit();
    }
}

Now, some of these methods calls other methods of the command class from within their transactions, for instance:

public void UpdateWithSomeCascadingStuff(someOtherEntity)
{
    using(var tx = _db.Database.BeginTransaction())
    {
        //Some updates to db
        _db.SaveChanges();

        //Some other cascading logic and updates to db
        var relatedEntityToUpdate = _query.GetSomeEntityToUpdate(someOtherEntity);
        UpdateStuff(relatedEntityToUpdate);
        _db.SaveChanges();
        tx.Commit();
    }
}

Clearly, by doing this, I am nesting EF transactions for the same DbContext instance.

Is this supported and will it cause any trouble? Are there any alternative approaches I can take?

UPDATE: I am using EF6 Code First

like image 404
CShark Avatar asked May 13 '16 14:05

CShark


1 Answers

EntityFramework's DBContexts implements both UnitOfWork and Repository patterns in itself.

The context in EF6 also automatically wraps all commits in a transaction in itself (if it is not already part of one).

So, no, you should not share a context between multiple units of work. They should each get their own.

UPDATE

If you try to start duplicate transactions on the same DbContext you get:

An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll

Additional information: The connection is already in a transaction and cannot participate in another transaction. EntityClient does not support parallel transactions.

So no, you can't do what you are asking for.

like image 115
Mattias Åslund Avatar answered Sep 21 '22 03:09

Mattias Åslund