Pregunta ¿Cómo maneja los errores de nivel de transporte en SqlConnection?


De vez en cuando, en una aplicación .NET de alto volumen, es posible que vea esta excepción cuando intente ejecutar una consulta:

System.Data.SqlClient.SqlException: un error de nivel de transporte tiene   ocurrido al enviar la solicitud al servidor.

Según mi investigación, esto es algo que "simplemente sucede" y no se puede hacer mucho para prevenirlo. No sucede como resultado de una mala consulta, y generalmente no se puede duplicar. Simplemente surge una vez cada pocos días en un sistema OLTP ocupado cuando la conexión TCP a la base de datos falla por alguna razón.

Me veo obligado a detectar este error analizando el mensaje de excepción y luego volviendo a intentar toda la operación desde cero, para incluir el uso de una nueva conexión. Nada de eso es bonito.

¿Alguien tiene alguna solución alternativa?


32
2017-08-19 17:36


origen


Respuestas:


publiqué una respuesta a otra pregunta sobre otro tema que podría tener algún uso aquí. Esa respuesta involucraba conexiones SMB, no SQL. Sin embargo, era idéntico en que implicaba un error de transporte de bajo nivel.

Lo que encontramos fue que en una situación de carga pesada, era bastante fácil para el servidor remoto desconectar las conexiones en la capa de TCP simplemente porque el servidor estaba ocupado. Parte de la razón fue que el número predeterminado de veces que TCP retransmitiría datos en Windows no era apropiado para nuestra situación.

Eche un vistazo a la configuraciones de registro para sintonizar TCP / IP en Windows. En particular, quieres mirar TcpMaxDataRetransmissions y tal vez TcpMaxConnectRetransmissions. Estos valores predeterminados son 5 y 2 respectivamente, intente subirlos un poco en el sistema cliente y duplicar la situación de carga.

No te vuelvas loco! TCP duplica el tiempo de espera con cada retransmisión sucesiva, por lo que el comportamiento de tiempo de espera para las conexiones incorrectas puede ser exponencial si usted las aumenta demasiado. Como recuerdo subir TcpMaxDataRetransmissions a 6 o 7 resolvió nuestro problema en la gran mayoría de los casos.


8
2017-10-16 07:50



Esta entrada en el blog por Michael Aspengren explica el mensaje de error "Se ha producido un error de nivel de transporte al enviar la solicitud al servidor".


3
2018-01-29 07:20



Para responder a su pregunta original:

Una forma más elegante de detectar este error en particular, sin analizar el mensaje de error, es inspeccionar el Number propiedad de la SqlException.

(Esto realmente devuelve el número de error del primer SqlError en el Errors colección, pero en su caso el error de transporte debería ser el único en la colección).


2
2017-10-01 05:57



use Enterprise Services con componentes transaccionales


1
2017-07-23 15:24



He visto esto suceder en mi propio entorno varias veces. La aplicación cliente en este caso está instalada en muchas máquinas. Algunas de esas máquinas son computadoras portátiles, la gente deja la aplicación abierta desconectándola y luego conectándola de nuevo e intentando usarla. Esto provocará el error que ha mencionado.

Mi primer punto sería mirar la red y asegurar que los servidores no estén en DHCP y renovar las direcciones IP que causan este error. Si ese no es el caso, entonces debe comenzar a atravesar los registros de eventos buscando otras redes relacionadas.

Desafortunadamente es como se indicó anteriormente un error de red. Lo principal que puedes hacer es simplemente monitorear las conexiones usando una herramienta como netmon y trabajar desde allí.

Buena suerte.


1
2017-10-31 06:30



También debe verificar la conectividad del hardware a la base de datos.

Tal vez este hilo será útil: http://channel9.msdn.com/forums/TechOff/234271-Contenction-forcibly-closed-SQL-2005/


0
2017-08-19 18:02



Estoy usando una capa de confiabilidad alrededor de mis comandos DB (abstraída en la interfaz del repositorio). Básicamente es solo código que intercepta cualquier excepción esperada (DbException y también InvalidOperationException, que sucede por problemas de conectividad), lo registra, captura estadísticas y vuelve a intentar todo nuevamente.

Con esa capa de confiabilidad presente, el servicio ha sido capaz de sobrevivir a pruebas de estrés de manera elegante (bloqueos muertos constantes, fallas de red, etc.). La producción es mucho menos hostil que eso.

PD: Hay más sobre eso aquí (junto con una forma simple de definir la confiabilidad con la interceptación DSL)


0
2017-10-01 04:53



Yo tuve el mismo problema. Le pregunté a mis amigos geek de la red, y todos dijeron lo que las personas han respondido aquí: es la conexión entre la computadora y el servidor de la base de datos. En mi caso, fue mi proveedor de servicios de Internet, o el enrutador ese el problema. Después de una actualización de enrutador, el problema desapareció. Pero, ¿tiene algún otro problema de conexión a Internet de su computadora o servidor? Tuve...


0
2017-10-01 06:05



Tuve el mismo problema, aunque fue con las solicitudes de servicio a una base de datos SQL.

Esto es lo que tenía en mi registro de errores de servicio:


System.Data.SqlClient.SqlException: se ha producido un error de nivel de transporte al enviar la solicitud al servidor. (provider: TCP Provider, error: 0 - Una conexión existente fue cerrada a la fuerza por el host remoto.)


Tengo un conjunto de pruebas de C # que prueba un servicio. El servicio y DB estaban en servidores externos, así que pensé que ese podría ser el problema. Así que implementé el servicio y DB localmente en vano. El problema continuó. El conjunto de pruebas ni siquiera es una prueba de rendimiento apremiante, así que no tenía idea de lo que estaba sucediendo. La misma prueba fallaba cada vez, pero cuando deshabilitaba esa prueba, otra fallaba continuamente.

Intenté con otros métodos sugeridos en Internet que tampoco funcionaron:

  • Aumente los valores de registro de TcpMaxDataRetransmissions y TcpMaxConnectRetransmissions.
  • Desactive la opción "Memoria compartida" dentro del Administrador de configuración de SQL Server en "Protocolos de cliente" y clasifique TCP / IP en el 1er lugar de la lista.
  • Esto puede ocurrir cuando prueba la escalabilidad con una gran cantidad de intentos de conexión del cliente. Para resolver este problema, utilice la utilidad regedit.exe para agregar un nuevo valor DWORD llamado SynAttackProtect a la clave de registro HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters \ con datos de valor de 00000000.

Mi último recurso fue utilizar la vejez diciendo "Intenta y vuelve a intentarlo". Así que he anidado las declaraciones try-catch para asegurarme de que si la conexión TCP / IP se pierde en el protocolo de comunicaciones inferior, no se da por vencido, sino que lo intenta de nuevo. Esto ahora me funciona, sin embargo, no es una solución muy elegante.


0
2017-07-23 15:19



Por lo que puedo decir, la clase 20 es el nivel de transporte.


0
2017-08-19 17:20