簡體   English   中英

NServiceBus和實體框架導致異常-基礎提供程序在打開時失敗

[英]NServiceBus and Entity Framework causes exception - The underlying provider failed on Open

我無法理解端點中的以下異常並對其進行故障排除。 我在SO上看到過很多關於此錯誤的文章,但毫無疑問反映了我們應用程序中的特定情況。

這是間歇性發生的 ,我之前曾嘗試通過增加Entity Framework的連接和命令超時來解決此問題。

端點和數據庫在同一台計算機上運行 該錯誤不會經常發生,僅可能發生於較大的更新或刪除。

附帶說明一下, 在調試時 ,我通常會得到“底層提供程序在Open上失敗”的信息。 我一直認為這是因為我在斷點上花費了太多時間,並且當我繼續時連接已關閉。

我想問一下在NServiceBus端點中使用/注入Entity Framework DbContext最佳實踐是什么? 是否最好通過NSB的依賴項注入來注入上下文? 像這樣:

public class ConfigureDependencyInjection : INeedInitialization
{
    public void Customize( BusConfiguration configuration )
    {
        configuration.RegisterComponents( reg =>
        {
            reg.ConfigureComponent<MyDbContext>( DependencyLifecycle.InstancePerCall );
        } );
    }
}

還是我不應該使用它,而是根據需要實例化上下文:

using (var context = new MyDbContext()) { ... }

此處處理的消息是一條單獨的物理消息,非常簡單明了-這就是為什么我選擇DependencyLifecycle.InstancePerCall的原因。

但是,在使用實體框架時,DependencyLifecycle.InstancePerUnitOfWork何時是正確的選項?

我該怎么做才能更好地調試此錯誤?

這是例外,還有堆棧:

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,盡管早期版本顯示相同的行為。

謝謝你的幫助。

約翰,當連接已經打開和關閉時,也會發生此錯誤,也許這就是問題所在。 但是,它似乎試圖加入分布式事務,但在此失敗。 如果是在調試時,您要調試多長時間? 可能是連接超時並且重試打開了關閉的連接? 您的連接超時是多少? 您正在使用什么交通工具? MSDTC是否打開? 並且您有什么想法,當它開始失敗? 它是不同的消息還是相同的?

不確定您的MyDbContext行為如何,但是我的總是這樣:

public class MyDbContext : DbContext
{
  public MyDbContext : base("MyConnectionString")
  {
  }
}

這樣,我可以確保它選擇了一個特定的連接字符串,而且我知道我不會忘記它,不會。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM