2011-08-10 26 views
14

Rol My Azure grabs stuff to process from a database - contiene una instancia de System.Data.SqlClient.SqlConnection y crea periódicamente una instancia SqlCommand y ejecuta una consulta SQL.¿Cómo trato la pérdida repentina de conexión a SQL Azure en mi rol de Azure?

Ahora de vez en cuando (por lo general una vez en varios días) que se ejecuta una consulta activará una excepción SqlException

El servicio ha encontrado un error al procesar su solicitud. Inténtalo de nuevo. Código de error 40143. Se produjo un error grave en el comando actual. Los resultados, si los hay, deben descartarse.

que ya he visto muchas veces y ahora mi código coge, llamadas Dispose() en el SqlConnection instancia y luego se vuelve a abrir la conexión y vuelve a intentar la consulta. Lo último generalmente resulta en otra excepción SqlException

Tiempo de espera caducado. El período de tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde.

Lo que se parece mucho a que el servidor SQL Azure no responde o no está disponible por alguna razón.

Actualmente mi código no capta la última excepción, se propaga fuera de RoleEntryPoint.Run() y la función se reinicia. El reinicio generalmente dura unos diez minutos y una vez que se completa, el problema desaparece durante aproximadamente un día.

No me gusta el reinicio de mi función, lleva un tiempo y la funcionalidad de mi servicio se ve obstaculizada. Me gustaría hacer algo más inteligente.

¿Cuál sería una estrategia para solucionar este problema? ¿Debo volver a intentar la consulta varias veces y cuántas veces y con qué intervalo? ¿Debería hacer algo más? ¿Cuándo me rindo y dejo que el rol se reinicie?

Respuesta

14

no te recomiendo que eche un vistazo en el Transient Fault Handling Framework for SQL Azure

Esto le ayudará a manejar la lógica de reintento para los dos intentos de conexión y de consulta, estoy usando esto en la producción y funciona muy bien. También hay un buen artículo on technet que podría ser de alguna utilidad.

[EDIT: 17 Oct 2013]

Parece que este ha sido recogido por el equipo de patrones y prácticas en The Transient Fault Handling Application Block

+0

Está disponible también vía nuget. – dunnry

+0

Gracias dunnry No había visto eso. Culpo a Wade por no mantenernos debidamente actualizados;) –

+5

Ese sitio de manejo de fallas transitorias tiene una falla intransigente: está inactivo. – Rory

2

Utilizamos TransientFaultHandling y no manejar todas las extrañas excepciones.

Por ejemplo, éste apareció ayer:

el servicio ha encontrado un error al procesar su solicitud. Inténtalo de nuevo. Código de error 40143. Se produjo un error grave en el comando actual. Los resultados, si los hay, deben descartarse. , StackTrace en System.Data.SqlClient.SqlConnection.OnError (excepción SqlException, Boolean breakConnection) en System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() en System.Data.SqlClient.TdsParser.Run (runBehavior RunBehavior, SqlCommand cmdHandler, .

El enfoque razonable que funcione incluso con esto:

  1. identificar un pseudo-transacciones de grano grueso donde sucede la llamada.
  2. Envuelva este bloque en un try-catch.
  3. en la excepción, 'retrotraer' la pseudo-transacción.

Ejemplo de un flujo de trabajo típico:

  • un GET cola de mensajes Azure
  • datos de consulta B desde SQL Azure
  • datos de proceso C,
  • D cargar los resultados de
  • E eliminar mensaje.

Envuelva B a C juntos en un try-catch. Si ocurre algo durante la llamada 'inofensiva' de SQL Azure, simplemente rescatar sin borrar el mensaje, simplemente aparecerá de nuevo después de que expire el tiempo de espera de visibilidad.

En realidad, este es un enfoque muy común: organízate en bloques de tipo transaccional, envuelve el bloque en try-catch, reinicia cuidadosamente la excepción. Y nunca, nunca asuma que algunas llamadas no fallan. Todas las llamadas fallan de vez en cuando.

+1

Estoy de acuerdo con su enfoque, pero la respuesta de David Steele también es correcta. De hecho, ambas respuestas se refieren a diferentes niveles. Utiliza el Marco de gestión de fallas transitorias para tratar los errores transitorios; si la situación persiste, cancela la operación actual y la vuelve a intentar más tarde (o descarta). –