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

Al procesar mensajes en flujos de mensajes, los errores pueden deberse a las siguientes causas:
  • 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 intermediario.
  • 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.

El diseñador de flujos de mensajes debe decidir cómo se van a manejar los errores.

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 intermediario. 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.

Si los nodos de entrada y salida se establecen en modalidad transaccional, el intermediario restaura el estado que había antes de que se procesara el mensaje:
  1. Se vuelve a transferir el mensaje de entrada que aparentemente se ha tomado de la cola de entrada.
  2. Se descarta cualquier mensaje de salida que el flujo haya grabado aparentemente en las colas de salida.
Si los nodos de entrada y salida no se establecen en modalidad transaccional:
  1. El mensaje de entrada tomado de la cola de entrada no se vuelve a transferir.
  2. 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 intermediario 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 por la que no se ha podido procesar el mensaje se anota en el Registro de sucesos del sistema (Windows) o en syslog (UNIX). Por lo tanto, el mensaje anómalo retrasa el proceso de los mensajes válidos subsiguientes y luego el intermediario 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 intermediario, 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

La lista siguiente contiene algunas sugerencias generales para crear manejadores de errores personalizados.
  • Si necesita algo mejor que el manejo de errores predeterminado, el primer paso es utilizar un manejador; consulte Sentencia DECLARE HANDLER. Cree un manejador por nodo, para interceptar todas las posibles excepciones (o tantas excepciones 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 THROW o un nodo para crear una excepción, que podría manejarse a un nivel más elevado en la lógica de flujo, o incluso alcanzar el nodo de entrada, lo que hará que la transacción se restituya; consulte Generar 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 de lógica podría constar de un nodo Database o Compute que graba un registro de anotaciones 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 Failure; consulte Estructura del á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 el apartado Manejar errores en flujos de mensajes. Consulte Generar una excepción y Captura del estado de la base de datos para ver ejemplos de lo que se puede hacer:

Escribir código para detectar errores

Los apartados siguientes presuponen que el intermediario detecta el error. Sin embargo, es posible que la lógica del flujo detecte un error. Por ejemplo, al codificar la lógica de flujo podría utilizar los siguientes elementos:
  • 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
Como ejemplo de un error detectado por la lógica de flujo, considere un campo que tenga un rango de posibles valores enteros que indica el tipo de mensaje. No sería recomendable dejar al azar lo que sucedería si llegara un mensaje en el que el valor del campo no se correspondiese con ningún tipo de mensaje conocido. Esta situación podría darse si el sistema se actualiza para dar soporte a tipos de mensaje adicionales, pero una parte del sistema no se actualiza.

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 intermediario no tiene ni idea de lo que contiene el 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 se aplica solamente a mensajes predefinidos, es decir MRM o IDoc.

Si el nodo de entrada se configura de este modo, los siguientes resultados están garantizados si el mensaje de entrada no se puede analizar satisfactoriamente:
  • 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

Los errores de base de datos se dividen en tres categorías:
  • La base de datos no funciona en absoluto (por ejemplo, está fuera de línea).
  • La base de datos funciona pero rechaza la petición (por ejemplo, se produce una contención de bloqueo).
  • La base de datos funciona pero lo que se le solicita que haga es imposible (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 la Sentencia DECLARE HANDLER) 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 cualquiera de las siguientes acciones:
  • 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

    Sin embargo, tenga cuidado con esta clase de estrategia. El manejador captura la excepción, por lo que todos los cambios en otras bases de datos, o las grabaciones en colas, se confirman.

Una base de datos rechaza su petición
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 petición 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.
Peticiones imposibles
El caso en el que la base de datos funciona pero lo que se le solicita que haga es imposible incluye una gran variedad de problemas.
Si, como en el ejemplo, la base de datos simplemente no tiene una tabla con el nombre que el flujo espera, el manejo de errores predeterminado es normalmente la mejor estrategia, excepto posiblemente registrar el error o pasar el mensaje a una cola especial.
No obstante, hay muchos otros errores que pueden manejarse satisfactoriamente. Por ejemplo, un intento de insertar una fila puede fallar porque ya existe dicha fila y la nueva fila sería un duplicado. O un intento de actualizar una fila puede fallar porque no existe dicha fila (es decir, la actualización ha actualizado cero filas). En estos casos, el manejador puede incorporar la lógica que se considere adecuada. Es posible que inserte la fila que falta o que utilice la fila existente (posiblemente asegurándose de que los valores que contiene son adecuados).
Nota: Para que una actualización de cero filas se indique como un error, la propiedad de nodo Tratar los avisos como errores ha de establecerse en true, que no es el valor predeterminado.

Utilización de la lógica propia para manejar errores en nodos de salida

Los errores que se producen en nodos MQOutpu indican 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

Además de los errores descritos más arriba, pueden producirse otros errores diversos. Por ejemplo, un cálculo aritmético se puede desbordar, una transformación CAST puede fallar porque los datos no son adecuados o un acceso a un campo de mensaje puede fallar debido a una restricción de tipo. El intermediario ofrece dos estrategias de programación para manejar estos tipos de 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.

Para ayudar en estas situaciones, los nodos Database y Compute tienen cuatro terminales llamados Out1, Out2, Out3 y 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.

Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Su opinión

Copyright IBM Corporation 1999, 2009Copyright IBM Corporation 1999, 2009.
Última actualización : 2009-02-16 13:53:56

ac17140_