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

err*_*ror 5 c# entity-framework transactions

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

  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();
   }
Run Code Online (Sandbox Code Playgroud)

返回异常:

已检测到环境事务.实体框架核心不支持环境事务.请参阅 http://go.microsoft.com/fwlink/?LinkId=800142

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

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

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

       scope.Complete();
 }
Run Code Online (Sandbox Code Playgroud)

我该如何实现呢?在方法中添加连接作为参数 - 似乎很荒谬.与连接的Init服务也是个坏主意.

Den*_*nov 1

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

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您将使用许多控制器/服务,那么您可以DbConnection使用内部方法来传递服务方法来执行此操作。您必须封装低层逻辑。

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

请参阅下一个答案,它们可以帮助您:

  • 如果交易是分布式交易怎么办?还支持吗?是否需要 MSDTC? (3认同)