繁体   English   中英

如何在 Entity Framework Core 中实现环境事务?

[英]How to implement ambient transaction in Entity Framework Core?

我需要在两种模型下实现事务(使用两个分离的有界上下文)。 所以代码如下:

  using (TransactionScope scope = new TransactionScope())
  {  
       //Operation 1
        using(var context1 = new Context1())
       {
           context1.Add(someCollection1);
           context1.SaveChanges();
       }
       //Operation 2
       using(var context2 = new Context2())
       {
           context2.Add(someCollection2);
           context2.SaveChanges();
       }

       scope.Complete();
   }

返回异常:

已检测到环境事务。 Entity Framework Core 不支持环境事务。 请参阅http://go.microsoft.com/fwlink/?LinkId=800142

在 Link 中,他们建议对两个上下文使用一个连接。 并在使用 context1 块中使用 context2。

但是如果我为每个模型使用自己的控制器/服务:

using (TransactionScope scope = new TransactionScope())
{  
      service1.DoWork();
      service2.DoWork();

       scope.Complete();
 }

我应该如何实施? 在方法中添加连接作为参数 - 似乎很荒谬。 带连接的初始化服务也是个坏主意。

您可以像这样使用“上下文”:

using (var context1 = new Context1())
{
    using (var transaction = context1.Database.BeginTransaction())
    {
        try
        {
            context1.Add(someCollection1);
            context1.SaveChanges();

            // if we don't have errors - next step 
            using(var context2 = new Context2())
            {
               // second step
               context2.Add(someCollection2);
               context2.SaveChanges();
            }   

            // if all success - commit first step (second step was success completed)
            transaction.Commit();
        }
        catch (Exception)
        {
            // if we have error - rollback first step (second step not be able accepted)
            transaction.Rollback();
        }
    }
}

如果您将使用许多控制器/服务,那么您可以使用内部方法将DbConnection传递到您的服务方法中。 必须封装底层逻辑。

带连接的初始化服务也是个坏主意。 - 也许你是对的。 但是您可以尝试使用一个连接和单个事务初始化两种方法。

查看下一个答案,它们可以帮助您:

使用下面的snipet

using (var context = new MyContext())
{
using (var transaction = context.Database.BeginTransaction())
{
    try
    {
        var customer = context.Customers
            .Where(c => c.CustomerId == 2)
            .FirstOrDefault();
            customer.Address = "43 rue St. Laurent";

        context.SaveChanges();
         
        var newCustomer = new Customer
        {
            FirstName = "Elizabeth",
            LastName = "Lincoln",
            Address = "23 Tsawassen Blvd."
        };
         
        context.Customers.Add(newCustomer);
        context.SaveChanges();

        transaction.Commit();
    }
    catch (Exception)
    {
        transaction.Rollback();
    }
}
}

更多详情: https : //entityframeworkcore.com/saving-data-transaction

你的声明How should I implement this?

using (TransactionScope scope = new TransactionScope())
{  
      service1.DoWork();
      service2.DoWork();

      scope.Complete();
 }

我正在使用 Controller > Service > Repository 模式,我发现在使用 async 选项时解决了相同的错误。 每个存储库都按照通常的方法在Startup.cs中注入了一个 db 上下文。 也许这是在较新版本的 .NET Core 中修复的,或者我只是在存储库中使用相同的上下文实例? 以下对我有用:

using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{  
      service1.DoWork();
      service2.DoWork();

      scope.Complete();
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM