出现Win32Exception:即使网络服务器负载较小,连接超时也会过期

时间:2018-07-30 12:00:21

标签: asp.net-core entity-framework-core

我已经在ASP.NET Core 2.1应用中像这样配置EF 2.1:

 services.AddDbContext<TacsDbContext>(
     options => options.UseSqlServer(connectionString, sql => sql.EnableRetryOnFailure()),
     ServiceLifetime.Transient, ServiceLifetime.Singleton);

每次重启应用后,在生产环境中运行几天后,我都会收到所有请求的消息:

  

System.Data.SqlClient.SqlException(0x80131904):连接超时   已过期尝试消耗以下内容时超时时间已过   登录前握手确认。这可能是因为   登录前握手失败或服务器无法响应   时间。尝试连接到该服务器所花费的时间   是-[登录前]初始化= 1470;握手= 1; ->   System.ComponentModel.Win32Exception(258):等待操作计时   

 at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
 at System.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()
 --- End of stack trace from previous location where exception was thrown ---
 at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
 at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
 at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
 at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)
 at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)
 at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
 at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken)
 at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken)
 at System.Linq.AsyncEnumerable.FirstOrDefault_[TSource](IAsyncEnumerable`1 source, CancellationToken cancellationToken)
 at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.TaskResultAsyncEnumerable`1.Enumerator.MoveNext(CancellationToken cancellationToken)
 at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken)
 at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken)
 at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
 at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteSingletonAsyncQuery[TResult](QueryContext queryContext, Func`2 compiledQuery, IDiagnosticsLogger`1 logger, Type contextType)
 at TACS.People.PeopleRepository.GetPersonInformation(String enterpriseId) in D:\a\1\s\TACS.People\PeopleRepository.cs:line 39
 at TACS.People.PeopleRepositoryExtensions.EnsurePerson(IPeopleRepository peopleRepository, String enterpriseId) in D:\a\1\s\TACS.People\PeopleRepositoryExtensions.cs:line 13
 at TACS.Web.AppCode.Auth.TacsClaimsTransformation.AddPersonId(ClaimsPrincipal principal) in D:\a\1\s\TACS.Web\AppCode\Auth\TacsClaimsTransformation.cs:line 77
 at TACS.Web.AppCode.Auth.TacsClaimsTransformation.TransformAsync(ClaimsPrincipal principal) in D:\a\1\s\TACS.Web\AppCode\Auth\TacsClaimsTransformation.cs:line 52
 at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
 at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
 at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
 at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
 at TACS.Web.Startup.<>c__DisplayClass6_0.<<Configure>b__0>d.MoveNext() in D:\a\1\s\TACS.Web\Startup.cs:line 172
 --- End of stack trace from previous location where exception was thrown ---
 at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
 at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
 ClientConnectionId:89feb963-e494-4f12-94fb-57aa18a2c116
 Error Number:-2,State:0,Class:11

似乎打开了太多连接。这是因为我已经使用了瞬态服务寿命吗?

我认为,每当我要访问数据库时,创建新的DbContext是一个好习惯。使用作用域生存期会导致每个请求将使用DbContext的单个实例,并且它看起来像反模式,因为可能会有多个工作单元。

0 个答案:

没有答案