我首先使用EF5代码,我需要在同一个事务中包含多个SaveChanges()
的调用。我对使用transactionScope相对较新,似乎无法调整其上的选项来完成我想要做的事情。
以下代码驻留在一个服务类中,该服务类注入了我的DbContext类的实例。我不会在这个类的任何地方创建额外的DbContext实例。
起初我尝试了以下内容。代码很干净,但它会尝试在SaveChanges
函数的GenerateInvoice
方法中升级到DTC。
using (var scope = new TransactionScope())
{
// This function does some work and calls SaveChanges
Guid invoiceId = GenerateInvoice(cart);
// This function also does some querying and calls SaveChanges
DeleteCart();
// Transaction should only commit if both functions above were successful
scope.Complete();
}
我做了一些研究,并将代码更改为以下内容,但不会升级到DTC,但我不确定它是否是最好的方法。
IObjectContextAdapter adapter = (IObjectContextAdapter)_context;
adapter.ObjectContext.Connection.Open();
using (var scope = new TransactionScope())
{
// This function does some work and calls SaveChanges
Guid invoiceId = GenerateInvoice(cart);
// This function also does some querying and calls SaveChanges
DeleteCart();
// Transaction should only commit if both functions above were successful
scope.Complete();
adapter.ObjectContext.Connection.Close();
}
是否有更简单的方法可以首先在多个SaveChanges
中使用EF5代码获得事务支持而不升级到DTC?
由于
答案 0 :(得分:2)
不是我找到的。它也是有道理的。通过不止一次调用SaveChanges()
,您可能会打开与数据库的多个连接。跨这些连接协调事务的唯一方法是使用分布式事务(因此MSDTC)。
我能想出的最佳解决方案是只拨打SaveChanges()
一次。这可能意味着重构一些代码,但最好是所有需要事务的实体都同时提交。
仅调用SaveChanges()
一次也允许EF更改跟踪器使用其缓存并在应用程序和数据库之间保存大量通信。