已经有一个与此命令关联的打开的 DataReader,必须先关闭该读取器并调用操作过滤器数据库



这有效

我有一个非常奇怪的问题正在发生。 我收到来自 API 调用的错误There is already an open DataReader associated with this Command which must be closed first.。 但是,此错误仅发生在这一个服务器上,而不是同时容纳数据库的主服务器上。

代码是精确的,web.config 是相同的,除了在主服务器上使用 localhost 的连接字符串。

此 API 调用使用会话 Cookie 属性来验证用户。 这是 asp.net 成员在这里发生的唯一独特事情。

唯一不同的是服务器错误关闭了TLS 1.0,但主服务器没有。 我也不想启用MultipleActiveResultSets因为这以前总是有效的。 任何帮助都会很棒。

https://example.com/api/v1/test/help?testid=109178&_COOKIE_=<cookie>

在下面的 Get 方法的操作上装饰的此过滤器上进行一些日志记录。

这是在 MVC 操作筛选器中。

var user = Membership.GetUser();
if (user != null)
{
if (Roles.IsUserInRole(RoleName.ScoreKeeper.ToString()))
{
var memberId = _apiAuthenticationService.ValidUser(new Guid(user.ProviderUserKey.ToString()));
if (memberId > 0)
{
apiAuthorizeRequest.MemberId = memberId;
return true;
}
}
}
public int ValidUser(Guid userId)
{
var apiMember = _membersRepository.Get(null, q => q.UserId == userId);
if (apiMember != null)
return apiMember.Id;
return 0;
}

堆栈跟踪

Stack Trace :   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
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.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at Tournaments.Data.Repositories.RepositoryBase`1.Get(Expression`1[] includes, Expression`1 where) in D:ProjectsTournaments.DataRepositoriesRepositoryBase.cs:line 110
at Tournaments.Services.Api.ApiAuthenticationService.ValidUser(Guid userId) in D:ApiApiAuthenticationService.cs:line 116

内部异常

Message :There is already an open DataReader associated with this Command which must be closed first.  Source :System.Data  Stack Trace :   at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)     at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)     at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)     at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)     at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)     at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)     at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)     at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)  TargetSite :Void ValidateConnectionForExecute(System.Data.SqlClient.SqlCommand)

这是一个并发问题;ActionFilterAttribute被视为单一实例,因此单个实例处理所有请求。
因此,多个并发请求共享同一个_apiAuthenticationService实例,该实例保存DbContext。这会导致同时在共享DbContext实例上执行同时执行查询/命令的可能性,该实例因给定的异常而失败。

您看到此错误的时间和频率取决于 Web 请求的流量以及DbContext/database 执行查询/命令的速度。
(该 TLS 错误可能已经导致一些延迟。

解决方案:不要在ActionFilter中使用共享状态;为每个请求单独解析/实例化依赖项。

相关内容

最新更新