Codificación de ESQL para manejar errores
Cuando se procesan mensajes en un flujo de mensajes, los errores pueden tener varias causas distintas y el diseñador del flujo de mensajes debe decidir cómo manejar dichos errores.
Introducción
- Causas externas; por ejemplo, el mensaje de entrada no es válido sintácticamente, se ha cerrado una base de datos utilizada por el flujo o falla la fuente de alimentación de la máquina en la que se ejecuta el nodo de integración.
- Causas internas; por ejemplo, un intento de insertar una fila en una
tabla de base de datos falla debido a una comprobación de restricción, o
una serie de caracteres que se lee en una base de datos no se puede
convertir en un número porque contiene caracteres alfabéticos.
Los errores internos pueden deberse a programas que almacenan datos no válidos en la base de datos o a un defecto en la lógica de un flujo.
Utilización del manejo de errores predeterminado
La estrategia más simple para manejar los errores de ESQL es no hacer nada y utilizar el comportamiento predeterminado del nodo de integración. El comportamiento predeterminado es interrumpir el proceso del mensaje anómalo y continuar con el mensaje siguiente. Los nodos de entrada y salida proporcionan opciones para controlar exactamente qué sucede cuando se interrumpe el proceso.
- Se vuelve a transferir el mensaje de entrada que aparentemente se ha tomado de la cola de entrada.
- Se descarta cualquier mensaje de salida que el flujo haya grabado aparentemente en las colas de salida.
- El mensaje de entrada tomado de la cola de entrada no se vuelve a transferir.
- Todos los mensajes de salida que el flujo ha grabado en las colas de salida permanecen en las colas de salida.
Cada una de estas estrategias tiene sus ventajas. El modelo transaccional mantiene la coherencia de los datos, mientras que el modelo no transaccional maximiza la continuidad del proceso de mensajes. En el modelo transaccional, el mensaje de entrada anómalo se vuelve a transferir a la cola de entrada y el nodo de integración intenta procesarlo otra vez. El resultado más probable de este escenario es que el mensaje continúe fallando hasta que se alcance el límite de reintentos, momento en el cual el mensaje se pone en una cola de mensajes no entregados. La razón de la anomalía para procesar el mensaje se registra en el registro de sucesos del sistema (Windows) o syslog (UNIX). Por lo tanto, el mensaje anómalo retrasa el proceso de los mensajes válidos subsiguientes y el nodo de integración lo deja sin procesar.
La mayoría de bases de datos operan de forma transaccional para que todos los cambios realizados en las tablas de base de datos se confirmen si el proceso del mensaje se realiza satisfactoriamente, o se restituyan si el proceso falla, manteniendo de este modo la integridad de los datos. Una excepción a esta situación es cuando falla el propio nodo de integración, o una base de datos (por ejemplo, hay un corte de corriente en los sistemas en los que se están ejecutando). En estos casos, los cambios podrían confirmarse en algunas bases de datos, pero en otras no, o los cambios de base de datos podrían confirmarse pero los mensajes de entrada y salida no se confirman. Si estas posibilidades le preocupan, coordine el flujo y configure las bases de datos implicadas.
Utilización del manejo de errores personalizado
- Si necesita algo mejor que el manejo de errores predeterminado, el primer paso es utilizar un manejador; consulte la sentencia DECLARE HANDLER. Cree un manejador por nodo para interceptar todas las excepciones posibles (o tantas como se puedan prever).
- Una vez que haya interceptado un error, el manejador de errores puede utilizar la lógica que sea apropiada para manejarlo. De forma alternativa, puede utilizar una sentencia o un nodo THROW para crear una excepción, que podría manejarse más arriba en la lógica de flujo, o incluso llegar al nodo de entrada, lo que hace que la transacción se retrotraiga; consulte Generación de una excepción.
- Si un nodo genera una excepción que el manejador no captura, el flujo se desvía al
terminal Failure (de anomalías), si hay uno conectado o, si no hay ningún terminal
Failure conectado, lo maneja el manejo de errores predeterminado.
Utilice terminales Failure (de anomalías) para capturar errores no manejados. Conecte un flujo de lógica simple al terminal Failure. Este flujo lógico puede consistir en una base de datos o un nodo Compute que graba un registro de anotaciones cronológicas en una base de datos (posiblemente incluyendo la corriente de bits del mensaje) o graba un registro en el registro de sucesos. El flujo también podría contener un nodo de salida que graba el mensaje en una cola especial.
El árbol de excepciones completo se pasa a cualquier nodo que esté conectado a un terminal de anomalías; consulte Árbol de lista de excepciones.
- Los manejadores de errores son responsables de registrar cada error en un lugar apropiado, por ejemplo el registro de sucesos del sistema.
Para obtener una descripción detallada de las opciones que puede utilizar para procesar errores en un flujo de mensajes, consulte Manejo de errores en flujos de mensajes. Para obtener ejemplos de lo que puede hacer, consulte Generación de una excepción y Captura del estado de la base de datos.
Escribir código para detectar errores
- Sentencias IF que se insertan específicamente para detectar situaciones que no deben producirse
- La cláusula ELSE de una sentencia o expresión CASE para detectar rutas en el código que no deben ser posibles
Utilización de la lógica propia para manejar mensajes de entrada que no son válidos
Es difícil manejar los mensajes de entrada que no son válidos sintácticamente (y los mensajes de entrada que parecen no ser válidos porque la información de formato de mensaje es errónea) porque el nodo de integración no puede determinar el contenido del mensaje. Normalmente, la mejor forma de manejar estos mensajes es configurar el nodo de entrada para analizar y validar totalmente el mensaje. Sin embargo, esta configuración solamente se aplica a mensajes predefinidos; es decir, MRM o IDoc.
- El mensaje de entrada no emerge nunca del terminal de salida normal del nodo (va al terminal Failure).
- El mensaje de entrada no entra nunca en la parte principal del flujo de mensajes.
- El mensaje de entrada no produce nunca actualizaciones de base de datos.
- No se graban mensajes en ninguna cola de salida.
Para manejar un mensaje anómalo, conecte un flujo de lógica simple al terminal Failure. La única desventaja de esta estrategia es que si el flujo normal no necesita acceso a todos los campos del mensaje, al forzar el análisis completo del mensaje el rendimiento se ve afectado.
Utilización de la lógica propia para manejar errores de base de datos
- La base de datos no funciona (por ejemplo, está fuera de línea).
- La base de datos funciona pero rechaza la solicitud (por ejemplo, se produce una contención de bloqueo).
- La base de datos funciona pero no puede realizar la acción solicitada (por ejemplo, leer en una tabla no existente).
Si necesita algo mejor que el manejo de errores predeterminado, el primer paso es utilizar un manejador (consulte DECLARE HANDLER statement) para interceptar la excepción. El manejador puede determinar la naturaleza de la anomalía a partir del estado de SQL que devuelve la base de datos.
- Una base de datos no funciona
- Si una base de datos no funciona en absoluto, y es esencial para el
proceso de mensajes, normalmente no se puede hacer gran cosa. El
manejador, después de determinar la causa, puede realizar una de las
siguientes acciones (o más de una):
- Utilizar la sentencia RESIGNAL para volver a generar el error original, lo que permite que el manejador de errores predeterminado tome el control
- Utilizar una base de datos diferente
- Grabar en el mensaje en una cola de salida especial
Tenga cuidado si utiliza una propuesta similar a esta técnica; el manejador captura la excepción, por lo que los cambios en otras bases de datos, o las grabaciones en colas, se confirman.
- Una base de datos rechaza su solicitud
- La situación en la que se produce una contención de bloqueo es similar
al caso
La base de datos no funciona
porque la base de datos habrá restituido todos los cambios de base de datos que haya realizado para el mensaje actual, no sólo la solicitud anómala. Por consiguiente, a menos que esté seguro que ésta era la única actualización, el manejo de errores predeterminado es la mejor estrategia, excepto posiblemente registrar el error o pasar el mensaje a una cola especial. - Solicitudes imposibles
- Se produce una solicitud imposible cuando la base de datos está en funcionamiento pero no puede llevar a cabo la acción solicitada. Este tipo de error abarca una gran variedad de problemas.
Utilización de la lógica propia para manejar errores en nodos de salida
Los errores que se producen en los nodos MQOutput informan de la naturaleza del error en el estado de SQL y proporcionan información adicional en la variable Error nativo de SQL . Por lo tanto, si se necesita algo mejor que el manejo de errores predeterminado, el primer paso es utilizar un manejador (consulte la sentencia DECLARE HANDLER) para interceptar la excepción. Normalmente, un manejador de este tipo sólo afecta a una sola sentencia PROPAGATE.
Utilización de la lógica propia para manejar otros errores
- El error produce una excepción que se maneja o se deja para restituir la transacción.
- La anomalía se registra como un valor especial que se comprueba más adelante.
En ausencia de una restricción de tipo, un intento de acceder a un campo de mensaje no existente da como resultado el valor nulo. Los valores nulos se propagan mediante expresiones, haciendo que el resultado sea nulo. Por lo tanto, si una expresión, por compleja que sea, no devuelve un valor nulo, sabrá que todos los valores que ésta necesitaba para calcular el resultado no eran nulos.
Las expresiones de transformación CAST pueden tener una cláusula predeterminada. Si hay una cláusula predeterminada, las transformaciones CAST fallan silenciosamente; en lugar de generar una excepción, simplemente devuelven el valor predeterminado. El valor predeterminado puede ser un número inocuo (por ejemplo, cero para un entero) o un valor que claramente no es válido en el contexto (por ejemplo, -1 para un número de cliente). Un valor nulo puede ser especialmente adecuado porque es un valor que es diferente de todos los demás, y se propagará mediante expresiones sin ninguna posibilidad de que la condición de error quede enmascarada.
Manejo de errores en otros nodos
Las excepciones que se producen en otros nodos (es decir, en sentido descendente de una sentencia PROPAGATE) las pueden captar los manejadores de la manera habitual. Sin embargo, el manejo inteligente de dichos errores plantea un problema: había otro nodo implicado en el error original, por lo que es probable que otro nodo, y no necesariamente el que ha originado la excepción, participe en el manejo del error.
Como ayuda en estas situaciones, los nodos Base de datos y Compute tienen cuatro terminales denominados Out1, Out2, Out3y Out4. Además, la sintaxis de la sentencia PROPAGATE incluye cláusulas de expresión de terminal, de origen de mensajes y de control para proporcionar más control sobre estos terminales.