EF6嵌套事务
问题描述:
我有一个命令服务类,它利用工作单元模式,通过实体框架用各种方法更新数据库(本例中为SQL Azure)。EF6嵌套事务
命令服务通过引用一个dbcontext实例来实例化,该实例的生命周期由我选择的DI框架管理。
一些命令服务类的方法包装的多个更新到数据库的事务中,例如:
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();
}
}
现在,一些方法调用从他们的交易中的命令类的其他方法,例如:
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();
}
}
显然,通过这样做,我为同一个DbContext实例嵌套了EF事务。
这是否被支持,它会导致任何麻烦?我可以采取其他方法吗?
更新: 我使用EF6代码第一次
答
的EntityFramework的DBContexts本身同时实现的UnitOfWork和信息库模式。
EF6中的上下文还自动将事务中的所有提交包装在自身中(如果它不是其中的一部分)。
所以,不,你不应该在多个工作单元之间共享上下文。他们应该各自拥有自己的。
UPDATE
如果你试图在你得到同样的DbContext开始重复的事务:
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.
所以,不,你不能做你所要求的。
谢谢,但这不能回答我的问题。 –
EF隐藏在客户端代码的接口后面(因为我需要能够轻松刷出存储机制而不影响客户端代码),并且还有一些CQRS正在进行。因此,我必须“包装”其UOW实施。如何,为什么和正确这是一个太长的讨论。我知道EF在SaveChanges之前在单个事务中包装指令。在我的情况下,我有多个SaveChanges调用,需要在单个事务中进行包装。再一次 - 不是在这里捍卫设计 - 我只是想知道我是否可以在另一个嵌套EF6交易。 –
我扩大了我的答案。希望有助于更好地回答你的问题 –