这个问题在一个简单的例子中不易重现,但是想知道是否有人有任何经验和提示,这就是问题:
using (TransactionScope txScope = new TransactionScope()) {
...
}
但是这给了我:
Microsoft分布式事务处理协调器(MSDTC)已禁用 网络交易。
我们的数据库管理员告诉我, MSDTC 已被禁用,无法安装。
因此,我正在尝试使用MetadataWorkspace创建自己的EntityConnection,并认为每个上下文将使用相同的EntityConnection 。然而,这证明几乎不可能尝试使其工作,例如,目前我继续得到上述错误,即使理论上两个上下文都在使用EntityConnection。例如,很难理解实体框架在何处/为何需要MSDTC。
之前有没有人走过这条路,有经验或代码示例要分享?
答案 0 :(得分:13)
嗯,问题很简单。
如果您使用的是sql server 2008,那么您应该没有这个问题,因为您有可升级的事务,并且由于.NET知道您使用相同的持久性存储(数据库),因此它不会将其提升为DTC并将其提交为本地。 look into promotable transaction with sql server 2008.
据我所知,Oracle正在使用其驱动程序来支持可促销事务,但我不知道状态,MS oracle驱动程序不支持它。 http://www.oracle.com/technology/tech/windows/odpnet/col/odp.net_11.1.0.7.20_twp.pdf
如果您使用的驱动程序不支持可升级事务,则.NET无法使用本地事务执行两个连接。您应该更改您的体系结构或说服数据库管理员安装MSDTC。
答案 1 :(得分:1)
我在SQL 2008,Entity Framework中遇到了类似的问题。
我定义了两个框架(EF1和EF2),但使用相同的连接字符串到sql 2008数据库。
当我在两者上使用嵌套的“usings”时,我得到了MSDTC错误。 例如,代码是这样的:
using (TransactionScope dbContext = new TransactionScope())
{
using (EF1 context = new EF1())
{
// do some EF1 db call
using (EF2 context2 = new EF2())
{
// do some EF2 db call
}
}
dbContext.Complete();
}
它并不像这样简单,因为它分为几种方法,但这是“使用”的基本结构。
修复方法是一次只打开一个。没有MTDSC错误,无需在db上打开分布式事务。
using (TransactionScope dbContext = new TransactionScope())
{
using (EF1 context = new EF1())
{
// do some EF1 db call
}
using (EF2 context2 = new EF2())
{
// do some EF2 db call
}
dbContext.Complete();
}
答案 2 :(得分:1)
我认为您需要做的是强制您的上下文共享单个数据库连接。然后,您将能够在单个事务中针对两个不同的上下文执行这两个操作。您可以通过将一个EntityConnection对象传递给两个上下文的构造函数来实现此目的。当然,这种方法需要您将此对象传递给更新DB的方法。
我最近blogged关于创建数据库上下文范围,这将使得使用多个EF上下文和事务变得更容易。