none
System.Data.Entity.Core.EntityException: The underlying provider failed on Open en SQLAZURE RRS feed

  • Pregunta

  • En nuestro entorno de desarrollo, tenemos una base de datos sql azure, la cual, siempre luego de un período de inactividad, presenta una desconexión “temporal”, al segundo intento, ésta vuelve a responder.  Esto no es puntual, ya lo corroboré innumerables ocasiones con pruebas unitarias, que -transcurrido 5 minutos de la última conexión- ésta se pierde, falla, se reintenta y funciona sin problemas.  ¿Por qué ocurre esto y cómo solucionarlo? En ambientes de pree-producción y producción esto sería fatal.

    ¿Alguien ha pasado por lo mismo? 
    Test method crwr.iteach.layer.connectorFacade.ConnectionString.Factory.Tests.ConnectionsStringMakerTests.BuildCredentialsObjectFromParameterTest threw exception: 
    
    System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception: The network path was not found
        at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, DbConnectionPool pool, String accessToken, Boolean applyTransientFaultHandling)
       at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
       at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
       at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
       at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
       at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, ref DbConnectionInternal connection)
       at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, ref DbConnectionInternal connection)
       at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, ref DbConnectionInternal connection)
       at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
       at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(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.DbConnectionDispatcher.<Open>b__36(DbConnection t, DbConnectionInterceptionContext c)
       at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch(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.Core.EntityClient.EntityConnection.<Open>b__2()
       at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
       at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Func`1 operation)
       at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action 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(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(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.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
       at System.Linq.Enumerable.ToList(IEnumerable`1 source)
       at crwr.iteach.layer.connectorFacade.ConnectionInformation.MicroServices.MicroServicsReader`1.crwr.iteach.layer.connectorFacade.Contracts.IMicroServiceReadable<T>.GetAllMicroServices() in MicroServicesReader.cs: line 82
       at crwr.iteach.layer.connectorFacade.ConnectionString.Factory.ConnectionsStringMaker.BuildCredentialsObjectFromParameter(SqlAzureEnvironment environment, SqlAzureMicroServiceDataSource typeOfMicroService) in ConnectionsStringMaker.cs: line 153
       at crwr.iteach.layer.connectorFacade.ConnectionString.Factory.Tests.ConnectionsStringMakerTests.BuildCredentialsObjectFromParameterTest() in ConnectionsStringMakerTests.cs: line 137
    


    martes, 1 de marzo de 2016 6:57

Respuestas

  • Seguramente ese comportamiento sea un artefacto del sistema de Pooling. Puede que la última conexión que cerraste y que se devolvió al Pool se pierda por inactividad debido a un timeout, y la siguiente vez que el programa la intenta usar da un error (por haberse cerrado desde el servidor, o haberse cerrado en algún firewall intermedio). Descartada esa conexión por error, se vuelve a abrir una nueva, la cual funciona.

    Recuerda que en todos los documentos que hablan sobre desarrollo con SQL Azure siempre se nos recuerda que todas las operaciones realizadas contra SQL Azure se deben programar para que hagan reintentos en caso de error. De lo contrario te arriesgas a que falle en producción, no ya solo en caso de un timeout como los que estás viendo, sino también (por ejemplo) en caso de que Azure detenga un servidor por razones de mantenimiento y levante otro en su lugar (cosa que sucede con bastante frecuencia).

    Si tu código cliente está hecho con Entity Framework, puedes activar la política de reintentos del propio EF, para no tener que programar tú mismo los reintentos:

    https://msdn.microsoft.com/en-us/data/dn456835.aspx

    martes, 1 de marzo de 2016 21:47
    Moderador