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
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.