2017-08-28 78 views
2

我需要在两个模型下实现事务(使用两个分离的有界上下文)。所以像这样的代码:如何在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(); 
    } 

回报例外:

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

链路他们建议使用两个方面一个连接。并且在使用context1的块中使用context2。

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

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

     scope.Complete(); 
} 

我应该如何实现呢?在方法中添加连接作为参数 - 看起来很荒唐。与连接初始化服务也不好主意。

+0

分享两个上下文之间的单一的DbConnection,然后你可以使用一个单一的交易对彼此而言。 “连接初始化服务”不是一个“坏主意”。正是出于这个原因,你的服务应该共享DbContext和DbConnection实例,你的依赖注入框架会为你处理。 –

+0

如果我在服务中添加dbConnection作为参数,那么在服务生活的所有工作时间内,我都会打开我的连接。我可以花1分钟获取数据,30分钟计算。那么即使不需要时也可以打开连接,这是否正常? – error

+0

如果你的服务实例是长期的(为什么?),那么你需要一些其他对象来表示一个工作单元。这是_assuming_你有一个合理的理由来使用多个DbContexts。 –

回答

0

您可以使用“语境”是这样的:

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到您的服务的方法,使用这种操作方法内部。你必须封装低层的逻辑。

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

看下答案,他们可以帮助你:

+0

如果事务是分布式事务怎么办?是否仍然支持?是否需要MSDTC? –

相关问题