2017-08-28 15 views
2

2つのモデル(2つの分離された境界付きコンテキストを使用)の下でトランザクションを実現する必要があります。このようなので、コード:Entity Frameworkコアでアンビエントトランザクションを実装する方法は?

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

復帰例外:アンビエントトランザクションが検出された

。エンティティフレームワークのコアは では周囲トランザクションをサポートしていません。彼らはアドバイス2つのコンテキストに対して1つの接続を使用するリンクで http://go.microsoft.com/fwlink/?LinkId=800142

を参照してください。 context1のブロックを使用するにはcontext2を使用します。

しかし、私はすべてのモデルのために専用のコントローラ/サービスを使用している場合:

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

     scope.Complete(); 
} 

は、どのように私はこれを実装する必要がありますか?メソッドのパラメータとして接続を追加する - 不合理に思われる。接続の初期化サービスも悪い考え。

+0

2つのコンテキスト間の単一たDbConnectionを共有し、そしてあなたは、単一のトランザクションを使用することができます両方のための。 「接続したInitサービス」は「悪い考え」ではありません。あなたのサービスはDbContextとDbConnectionのインスタンスをこのような理由で共有する必要があり、依存関係注入フレームワークがこれを処理します。 –

+0

サービスのパラメータとしてdbConnectionを追加すると、サービスの稼動中に接続が開かれることがあります。データを取得するのに1分、計算に30分かかることがあります。それで、それが必要でないときでさえ私はオープンな接続を持っているのが普通ですか? – error

+0

サービスインスタンスが長寿命(理由は?)の場合、作業ユニットを表すために他のオブジェクトが必要です。そして、あなたが複数のDbContextを使用する正当な理由があることを訴えています。 –

答えて

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を渡すことができるよりも。下層のロジックをカプセル化する必要があります。

接続の初期化サービスにも悪い考えがあります。 - あなたが正しいかもしれません。しかし、1つの接続と1つのトランザクションで2つのメソッドを初期化することができます。

は、次の回答を参照してください、彼らはあなたを助けることができる:

+0

トランザクションが分散トランザクションの場合はどうなりますか?まだサポートされていますか?MSDTCが必要ですか? –

関連する問題