EF6 Nested Transactions

c# entity-framework entity-framework-6

Question

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

1
6
5/13/2016 2:50:22 PM

Accepted Answer

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.

2
5/13/2016 4:05:09 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow