エンドポイントで次の例外の理解とトラブルシューティングに問題があります。私はSOのこのエラーに関する多くの記事を見てきましたが、アプリケーションの特定のシナリオを反映した質問はありません。このNServiceBusおよびEntity Frameworkで例外が発生する - 公開時に基になるプロバイダが失敗しました
が断続的に起こる、と私は以前にEntity Frameworkのため接続とコマンドのタイムアウトの両方を増やすことでこの問題を解決しようとしました。
エンドポイントとデータベースは同じマシンで実行されています。エラーは非常に頻繁に発生するのではなく、大規模な更新や削除の場合にのみ発生します。
補足として、私は定期的にのデバッグ中に "基礎となるプロバイダがオープンに失敗しました"というメッセージを受け取ります。私はいつもブレークポイントに時間をかけすぎていたと思っていました。
ベストプラクティスは、NServiceBusエンドポイントでエンティティフレームワークのDbContextを使用/注入するためのベストプラクティスですか? NSBの依存関係注入を介してコンテキストを注入するのが最善でしょうか?そのように:
public class ConfigureDependencyInjection : INeedInitialization
{
public void Customize(BusConfiguration configuration)
{
configuration.RegisterComponents(reg =>
{
reg.ConfigureComponent<MyDbContext>(DependencyLifecycle.InstancePerCall);
});
}
}
または私はこれを使用してすべきではありませんが、代わりに、必要に応じてコンテキストをインスタンス化します。ここでは扱われ
using (var context = new MyDbContext()) { ... }
メッセージは、1つの物理メッセージ、非常に単純です - 私はDependencyLifecycle.InstancePerCallを選んだのです。
ただし、DependencyLifecycle.InstancePerUnitOfはEntity Frameworkを使用するとき正しいオプションですか?
このエラーをより詳細にデバッグするにはどうすればよいですか?ここで
は例外であり、スタック:
The underlying provider failed on Open.
The operation is not valid for the state of the transaction.
at System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction, Guid promoterType)
at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Guid promoterType)
at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification)
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.PrepareConnection(DbConnection owningObject, DbConnectionInternal obj, Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action`2 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.Open(DbConnection connection, DbInterceptionContext interceptionContext)
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
--- End of inner exception stack trace ---
at System.Data.Entity.Core.EntityClient.EntityConnection.Open()
at System.Data.Entity.Core.Objects.ObjectContext.EnsureConnection(Boolean shouldMonitorTransactions)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(List`1 collection, MergeOption mergeOption)
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.DeferredLoad()
at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.LoadProperty[TItem](TItem propertyValue, String relationshipName, String targetRoleName, Boolean mustBeNull, Object wrapperObject)
at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.<>c__DisplayClass7`2.<GetInterceptorDelegate>b__1(TProxy proxy, TItem item)
at System.Data.Entity.DynamicProxies.JournalTransaction_4CAE8D09C8D2614F98562EAA87E63CE3B6D4E9A6DEC760505C0C7C7C42295ECE.get_TransactionItems()
以前のバージョンが同じ挙動を示すが、これは、NSB 5.2.14用です。
ありがとうございました。
はい私のDbContextはあなたのものとまったく同じです。私の接続タイムアウトは、接続タイムアウト= 180です---私はいつも急いでデバッグするので、私はエラーを取得しないでください。しかし生産では、私は知らない。 MSDTCはローカルDBであってもオンにする必要がありますか?それでなぜ100%の時間に失敗するのではなく、3/100に過ぎないのでしょうか?あなたの入力とthouhgtsをありがとう。 – John
永続性としてSQLを使用している場合にのみ、トランスポートと独自のデータ(EFによってアクセスされる)が同じデータベースにあり、接続文字列がすべて同じ場合、MSDTCは使用されません。もちろん、あなたの運送や永続性が取引をサポートしていない場合。 基本的に、MSMQ + SQL Serverを何かに使用すると、分散トランザクションになります。トランザクションマネージャは自分のリソースのみを管理できるため、2つのトランザクションマネージャはMSDTCを意味します。 –