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

发布于 2024-08-24 09:32:26 字数 915 浏览 3 评论 0原文

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

  • 使用 Entity Framework
  • 在应用程序中有很多点,其中 (1) 数据被写入一些实体表,例如客户,(2)数据被写入历史
  • 这两个这些操作使用实体框架,但是,他们使用 >不同上下文
  • 中,这些操作需要同时在一个事务中:即,如果一个写入失败,另一个不应写入,等等。
  • 我可以用 TransactionScope 包装它们,

如下所示:

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

但这给了我:

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

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

因此,我正在尝试使用 MetadataWorkspace 创建自己的 EntityConnection 进行更改,其想法是每个上下文都将使用相同的 EntityConnection。然而,事实证明,试图让它工作几乎是不可能的,例如,目前我继续收到上述错误,即使理论上两个上下文都使用 EntityConnection。例如,很难理解实体框架在哪里/为什么需要 MSDTC。

以前有人走过这条路吗?有经验或代码示例可以分享吗?

This problem is not readily reproducible in a simple example here but was wondering if anyone has any experience and tips, here is the issue:

  • using Entity Framework
  • have many points in application where (1) data is written to some entity table e.g. Customer, (2) data is written to history table
  • both of these actions use Entity Framework, HOWEVER, they use different contexts
  • these actions need to be both in one transaction: i.e. if one fails to write, the other should not write, etc.
  • I can wrap them with a TransactionScope,

like this:

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

but this gives me:

Microsoft Distributed Transaction Coordinator (MSDTC) is disabled for
network transactions.

Our database admin has told me that MSDTC is disabled by choice and can not be installed.

Hence I am making changes trying to create my own EntityConnection with a MetadataWorkspace with the idea that each context will use the same EntityConnection. However, this is proving near impossible trying to get it to work, e.g. currently I continue to get the above error even though theoretically both contexts are using EntityConnection. It's difficult to understand where/why Entity Framework is requiring the MSDTC for example.

Has anyone gone down this road before, have experience or code examples to share?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余罪 2024-08-31 09:32:27

嗯,问题很简单。

如果您使用的是 sql server 2008,您不应该遇到这个问题,因为您有可提升的事务,并且 .NET 知道您正在使用相同的持久性存储(数据库),它不会将其提升为 DTC 并将其提交为本地。 查看 sql server 2008 的 promotable 事务。

据我所知 Oracle正在其驱动程序中支持promotable transactions,但我不知道状态,MS oracle 驱动程序不支持它。
http://www.oracle。 com/technology/tech/windows/odpnet/col/odp.net_11.1.0.7.20_twp.pdf

如果您使用的驱动程序不支持可提升事务,则 .NET 不可能使用本地事务执行两个操作连接。您应该更改体系结构或说服数据库管理员安装 MSDTC。

Well, the problem is quite easy.

If you are using sql server 2008 you should not have that problem because you have promotable transaction, and as .NET knows that you are using the same persistence store (the database) it wont promote it to DTC and commit it as local. look into promotable transaction with sql server 2008.

As far as I know Oracle is working in its driver to support promotable transactions, but I do not know the state, MS oracle driver does not support it.
http://www.oracle.com/technology/tech/windows/odpnet/col/odp.net_11.1.0.7.20_twp.pdf

If you are using a driver that do not support promotable transactions it is impossible for .NET to use local transaction doing two connections. You should change your architecture or convince the database admin for installing MSDTC.

回忆凄美了谁 2024-08-31 09:32:27

我在 SQL 2008、实体框架方面也遇到了类似的问题。

我定义了两个框架(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();
}

它并不像这样简单,因为它被分成几个方法,但这是“usings”的基本结构。

修复方法是一次仅打开一个使用。没有 MTDSC 错误,无需在数据库上打开分布式事务。

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();
}

I had a similar problem with SQL 2008, Entity Framework.

I had two frameworks defined (EF1, and EF2) but using identical connection strings to a sql 2008 database.

I got the MSDTC error above, when using nested "usings" across both.
eg the code was like this:

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();
}

It wasnt as simple as this, because it was split across several methods, but this was the basic structure of "usings".

The fix was to only open one using at a time. No MTDSC error, No need to open distributed transactions on 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();
}
意犹 2024-08-31 09:32:27

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

我最近 博客,这将使使用多个 EF 上下文和事务变得更容易。

I think that what you need to do is to force your contexts to share single database connection. You will be able then to perform these two operations against two different contexts in single transaction. You can achieve this by passing one EntityConnection object to both of your context's constructors. Of course this approach will require you to pass this object to methods which update DB.

I have recently blogged about creating database context scope which will make using multiple EF contexts and transactions easier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文