簡體   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