2016-10-25 42 views
0

私はTransactionScopeを使用する関数を持っています。私が2つのdbContextを使用すると、クラッシュします。エラーメッセージは、次のとおり2つのDBContextでTransactionScopeを使用するとエラーが発生する

System.Data.EntityException: Error underlying provider Open. ---> System.Transactions.TransactionException: The operation is not valid for the state of the transaction. in System.Transactions.TransactionState.EnlistPromotableSinglePhase (InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction AtomicTransaction, Guid promoterType) in System.Transactions.Transaction.EnlistPromotableSinglePhase (IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Guid promoterType) in System.Transactions.Transaction.EnlistPromotableSinglePhase (IPromotableSinglePhaseNotification promotableSinglePhaseNotification) in System .Data.SqlClient.SqlInternalConnection.EnlistNonNull (Transaction tx) in System.Data.SqlClient.SqlInternalConnection.Enlist (Transaction tx) 
in System.Data.ProviderBase.DbConnectionInternal.ActivateConnection (Transaction transaction) in System.Data.ProviderBase.DbConnectionPool.PrepareConnection (DbConnection owningObject, DbConnectionInternal obj, Transaction transaction) in System.Data.ProviderBase.DbConnectionPool.TryGetConnection (DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout , allowCreate Boolean, Boolean onlyOneCheckConnection, DbConnectionOptions UserOptions, DbConnectionInternal & connection) in System.Data.ProviderBase.DbConnectionPool.TryGetConnection (DbConnection owningObject, TaskCompletionSource1 retry, DbConnectionOptions 
    UserOptions, DbConnectionInternal & connection) in 
    System.Data.ProviderBase.DbConnectionFactory.TryGetConnection (DbConnection 
    owningConnection, TaskCompletionSource1 retry, DbConnectionOptions UserOptions, DbConnectionInternal oldConnection, DbConnectionInternal & connection) in System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal (DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions UserOptions) in 
    System.Data.SqlClient.SqlConnection.TryOpenInner (TaskCompletionSource1 retry) in System.Data.SqlClient.SqlConnection.TryOpen (TaskCompletionSource`1 retry) in System.Data.SqlClient.SqlConnection.Open() in System.Data.EntityClient.EntityConnection. OpenStoreConnectionIf (Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String ExceptionCode, attemptedOperation String, Boolean & closeStoreConnectionOnFailure) 

コード

public void example(int c, IEnumerable<int> pi, string comm) 
{ 
    using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead })) 
    { 
     var idsList = pi.ToList(); 
     foreach (var playlist in Context.pl.Where(p => idsList.Contains(p.pid) && p.c== c&& p.stat== 1)) 
     { 
      playlist.TimestampAuthorized = null; 

      var pl = "sss"; 
      notif.generateNotifForUser((new Notification(1, 1, pl, 2, 2))); 
     } 
     Context.SaveChanges(); 
     transactionScope.Complete(); 
    } 
} 

問題がContext.SaveChanges()で起こります。 私がnotif.generateNotifForUser();という行にコメントするとうまくいきます。その関数の中に、私もcontext.saveChanges();

おかげ

+2

例外の詳細を知ることは、タイプ、メッセージなどのように役に立ちます。 – Amy

+0

私は投稿に追加しました。 –

+1

英語で例外メッセージを提供できますか。 – Igor

答えて

1
// code before unchanged 
foreach (var playlist in Context.pl.Where(p => idsList.Contains(p.pid) && p.c== c&& p.stat== 1).ToList()) // added ToList 
// code after unchanged 

問題は、2つのものに対してオープンな接続を使用しようとしているという事実と関係しています。 pl DbSetの結果と、generateNotifForUserで何をやっているのかは、DbContext(あなたのアップデートに基づいて、の呼び出しを行っています)から何か他のものを取得している/これを修正するには、Lamdaステートメントの最後にToListを追加して、反復の開始直前に照会結果を完全に実現させる必要があります。その後、コードの他の部分でDbContextを引き続き使用できるように、接続が開かなくなります。これは、メソッドチェーン内で同様のミスをさらに起こしていないことを前提としています。

0

EDIT行います

をまた、あなたは一度だけContext.SaveChangesを呼び出す必要がContext.SaveChanges

を呼んでいたので、通知方法は、エラーの原因となったことが表示されます

通知方法でContext.SaveChangesを削除し、トランザクションの終了時に1度だけ呼び出しますpe。

+2

"foreachループのようにContextにアクセスすべきではありません。" **なぜ**? – Amy

+0

foreachループでIEnumerableで列挙しようとすると、同様の問題が発生します。ループを反復するたびに列挙しようとします。 – Adosi

+2

私たちの職業に関する素晴らしいことは、コードが予測可能であることです。 「奇妙なこと」は起こるだけではなく、コンポーネントやコードがそのように動作する理由は常にあります。私は論理的な方法では説明できないコードの問題にまだ遭遇していません。 "奇妙なことが起きる時は..."と答えると、それ以降のものはすべて無効になります(IMO)。 – Igor

関連する問題