【发布时间】:2016-04-30 07:42:34
【问题描述】:
我无法理解端点中的以下异常并对其进行故障排除。我在 SO 上看到了很多关于此错误的帖子,但毫无疑问反映了我们应用程序中的特定场景。
这间歇性发生,我之前尝试通过增加实体框架的连接和命令超时来解决这个问题。
端点和数据库在同一台机器上运行。该错误不会经常发生,仅可能用于较大的更新或删除。
作为旁注,我经常在调试时得到“底层提供程序在打开时失败”。我一直认为这是因为我在断点上花费了太多时间,并且在我继续时连接已关闭。
我想问在 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()) { ... }
这里处理的消息是一条物理消息,非常直接——这就是我选择 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,尽管早期版本显示相同的行为。
感谢您的帮助。
【问题讨论】:
标签: c# .net entity-framework dependency-injection nservicebus