2008-08-19 12 views
32

De vez en cuando en una aplicación .NET alto volumen, es posible que vea esta excepción cuando intenta ejecutar una consulta:¿Cómo maneja los errores de nivel de transporte en SqlConnection?

System.Data.SqlClient.SqlException: A transport-level error has occurred when sending the request to the server.

Según mi investigación, esto es algo que "simplemente sucede" y no mucho se puede hacer 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.

Estoy 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?

+0

Aumente la memoria RAM –

+0

¿Tiene estadísticas para la carga en su servidor de base de datos cuando se producen estos errores? Es posible que tenga problemas con la base de datos que causan fallas en las conexiones. –

+1

Esto * no debería * suceder, incluso en un volumen de transacciones alto. Ejecutamos un promedio de 25,000 transacciones por segundo en SQL Server 2005 Standard, y no obtenemos este error. (A menos que el clúster falle, que es cada 12+ meses, no cada pocos días). Sin más información, parece que hay un problema de red entre su servidor de base de datos y sus servidores de aplicaciones. ¿Puedes publicar más información? – Portman

Respuesta

0

estoy usando fiabilidad capa alrededor de mis comandos de base de datos (abstraído en el interfaece 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 pruebas de estrés con elegancia (bloqueos muertos constantes, fallas de red, etc.). La producción es mucho menos hostil que eso.

PS: There is more on that here (junto con una forma sencilla de definir fiabilidad con el DSL intercepción)

2

Para responder a su pregunta original:

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

(En realidad, esto devuelve el número de error desde el primer SqlError en la colección Errors, pero en su caso el error de transporte debe ser el único en la colección.)

+0

+1 no una respuesta, pero es una idea útil. –

0

que tenían 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 ...

8

He publicado an answer on another question 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 agotar 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 al registry settings for tuning TCP/IP en Windows.En particular, desea consultar TcpMaxDataRetransmissions y quizás 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, el aumento de TcpMaxDataRetransmissions a 6 o 7 resolvió nuestro problema en la gran mayoría de los casos.

1

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 tiene que 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.

3

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

0

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. (Proveedor: Proveedor de TCP, error:. 0 - Una conexión existente forzosamente fue cerrada por el host remoto)


que tiene un conjunto de pruebas de C# que pone a 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.

He intentado otros métodos sugeridos en Internet que no funciona bien:

  • aumentar los valores de registro de TcpMaxDataRetransmissions y TcpMaxConnectRetransmissions.
  • Desactive la opción "Memoria compartida" en el 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 "Intentar y probar de nuevo". 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

Gracias por los comentarios. Si está utilizando la agrupación de conexiones, intente llamar a SqlConnection.Recycle() cada 10 minutos para asegurarse de que si SQLServer ha cancelado una conexión que su grupo aún no intenta hacer uso de ella. Si esto funciona, informe de nuevo! – TheLegendaryCopyCoder

1

utilizar los servicios de la empresa con componentes transaccionales

0

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

0

Experimenté el error de transporte esta mañana en SSMS mientras estaba conectado a SQL 2008 R2 Express.

Estaba intentando importar un archivo CSV con \ r \ n. Codifiqué mi terminador de fila para 0x0d0x0a. Cuando lo cambié a 0x0a, el error se detuvo. Puedo cambiarlo de un lado a otro y verlo suceder/no suceder.

BULK INSERT #t1 FROM 'C:\123\Import123.csv' WITH 
     (FIRSTROW = 1, FIELDTERMINATOR = ',', ROWTERMINATOR = '0x0d0x0a') 

Sospecho que no estoy escribiendo mi terminador de fila correctamente porque SQL analiza un carácter a la derecha, mientras que el tiempo que estoy tratando de pasar dos caracteres.

De todos modos, este error tiene 4 años ahora, pero puede proporcionar un poco de información para el próximo usuario.

+0

Creo que el problema aquí fue que se suponía que el determinador de filas era un único valor binario, que para el servidor SQL se escribiría como 0x0d0a (sin segundos 0x). – Zastai

+0

¡Oye! ¡Eso es genial! ¡Lo intentaré más tarde esta noche! –

0

Solo quería publicar una solución aquí que funcionó para nuestra empresa en el nuevo software que hemos instalado. Recibimos el siguiente error desde el día 1 en el archivo de registro del cliente: El servidor no pudo procesar la solicitud. ---> Se ha producido un error de nivel de transporte al recibir resultados del servidor. (provider: TCP Provider, error: 0 - El período de tiempo de espera del semáforo ha expirado.) ---> El período de tiempo de espera del semáforo ha expirado.

Lo que solucionó completamente el problema fue configurar un agregado de enlace (LAG) en nuestro conmutador. Nuestro servidor Dell FX1 tiene líneas de fibra redundantes que salen de la parte posterior. No nos dimos cuenta de que el interruptor en el que están enchufados necesitaba tener un LAG configurado en esos dos puertos. Vea los detalles aquí: https://docs.meraki.com/display/MS/Switch+Ports#SwitchPorts-LinkAggregation

Cuestiones relacionadas