如何在没有MSDTC的情况下在TransactionScope中运行两个实体框架上下文?

entity-framework msdtc transactions

这个问题在这里的一个简单例子中不易重现,但是想知道是否有人有任何经验和提示,这里是问题:

  • 使用实体框架
  • 在应用程序中有许多要点,其中(1)数据被写入某个实体表,例如Customer,(2)数据被写入历史
  • 这两个动作都使用实体框架,但是,它们使用不同的上下文
  • 这些操作需要同时在一个事务中 :即如果一个人不能写,另一个不应该写,等等。
  • 我可以用TransactionScope包装它们,

像这样:

using (TransactionScope txScope = new TransactionScope()) {
    ...
}

但这给了我:

Microsoft分布式事务处理协调器(MSDTC)已禁用网络事务。

我们的数据库管理员告诉我, MSDTC被禁用, 无法安装

因此,我正在尝试使用MetadataWorkspace创建自己的EntityConnection,并认为每个上下文将使用相同的EntityConnection 。然而,这证明几乎不可能试图让它工作,例如,即使理论上两个上下文都在使用EntityConnection,我仍然继续得到上述错误。例如,很难理解实体框架在何处/为何需要MSDTC。

有没有人走过这条路,有经验或代码示例分享?

一般承认的答案

嗯,问题很简单。

如果您使用的是sql server 2008,则不应该有这个问题,因为您有可升级的事务,并且由于.NET知道您使用相同的持久性存储(数据库),因此它不会将其提升为DTC并将其提交为本地。 查看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。


热门答案

我认为您需要做的是强制您的上下文共享单个数据库连接。然后,您将能够在单个事务中针对两个不同的上下文执行这两个操作。您可以通过将一个EntityConnection对象传递给两个上下文的构造函数来实现此目的。当然,这种方法需要您将此对象传递给更新DB的方法。

我最近写了一篇关于创建数据库上下文范围的博文 ,这将使得使用多个EF上下文和事务更容易。



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因