Codificación de ESQL para manejar errores

Introducción

Al procesar mensajes en los flujos de mensajes, los errores se pueden deber a:
  1. Causas externas. Por ejemplo, el mensaje de entrada no es sintácticamente válido, 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.
  2. Causas internas. Por ejemplo, un intento de inserción de una fila en una tabla de base de datos falla debido a una comprobación de restricción o porque una serie de caracteres leída de una base de datos no se puede convertir en un número porque contiene caracteres alfabéticos.

    Los errores internos los pueden producir programas que almacenan datos no válidos en la base de datos o se pueden producir debido a un defecto en la lógica de un flujo.

El diseñador de flujo de mensajes debe reflexionar detenidamente sobre los errores y decidir cómo se deben manejar.

Utilización del manejo de errores por omisión

La estrategia más simple para manejar los errores de ESQL es no hacer nada y utilizar el comportamiento por omisión del intermediario. El comportamiento por omisión es atajar el proceso del mensaje anómalo y continuar en el mensaje siguiente. Los nodos de entrada y salida proporcionan opciones para controlar exactamente qué sucede cuando se ataja el proceso.

Si los nodos de entrada y salida se establecen en modalidad transaccional, el intermediario restaura el estado que tení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 aparentemente el flujo haya grabado 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. Los mensajes de salida que el flujo ha grabado en las colas de salida permanecen allí.

Cada una de estas estrategias tiene sus ventajas. El modelo transaccional conserva la coherencia de los datos, mientras que el modelo no transaccional maximiza la continuidad del proceso de mensajes. Recuerde que en el modelo transaccional, el mensaje de entrada anómalo se vuelve a transferir a la cola de entrada y el intermediario intentará procesarlo otra vez. El resultado más probable de esto es que el mensaje continúe fallando hasta que se alcance el límite de reintentos, momento en el cual se pone en una cola de mensajes no entregados. La razón por la que no se ha podido procesar el mensaje se registra en el registro de sucesos del sistema (Windows) o syslog (UNIX). De este modo, el mensaje anómalo retiene el proceso de los mensajes correctos subsiguientes durante un tiempo y, a continuación, 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. Existe una excepción de esto cuando falla el propio intermediario o una base de datos. (Por ejemplo, se puede interrumpir la alimentación de las máquinas que se están ejecutando.) En estos casos, es posible que los cambios se confirmen en algunas bases de datos y que no se confirmen en otras o que los cambios de base de datos se confirmen pero que los mensajes de entrada y salida no. Si estas posibilidades le preocupan, se deberá coordinar el flujo y se deberán configurar para este modo de trabajo las bases de datos implicadas.

Utilización del manejo de errores personalizado

A continuación se proporcionan algunas sugerencias generales para crear manejadores de errores personalizados:
  1. Si necesita algo mejor que el manejo de errores por omisión, el primer paso es utilizar un manejador (consulte el apartado Sentencia DECLARE HANDLER). Cree un manejador por nodo, para interceptar todas las posibles excepciones (o tantas excepciones como se puedan prever).
  2. Al interceptar 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 se puede manejar 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.
  3. Si un nodo genera una excepción que el manejador no capta, el flujo se desvía al terminal de anomalías, si hay alguno conectado, o, si no hay ninguno conectado, lo maneja el manejo de errores por omisión.

    Utilice terminales de anomalías para captar errores no manejados. Conecte un flujo de lógica simple al terminal de anomalías. Este flujo de lógica puede constar de una base de datos o un nodo 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. También puede contener un nodo de salida que graba el mensaje en una cola especial.

    El árbol de excepción completo se pasa a cualquier nodo conectado a un terminal de anomalías. (El árbol de excepción se describe en el apartado Estructura del árbol Lista de excepciones.)

  4. 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. Los temas siguientes proporcionan ejemplos de lo que se puede hacer:

Codificación para detectar errores

Los apartados siguientes suponen que es el intermediario quien detecta el error. Sin embargo, es bastante posible que la lógica del flujo detecte un error. Por ejemplo, al codificar la lógica de flujo puede utilizar:
  • Sentencias IF insertadas específicamente para detectar situaciones que no se deben producir
  • La cláusula ELSE de una sentencia o expresión CASE para atrapar rutas mediante 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 valores enteros posibles que indica el tipo de mensaje. En ese caso, no es recomendable dejar al azar lo que sucederá si llega un mensaje en el que el valor del campo no corresponde a ningún tipo de mensaje conocido. Esto puede suceder si el sistema se actualiza para soportar tipos de mensaje adicionales pero no se actualiza una parte del sistema.

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. Probablemente el mejor modo de tratarlos consiste en configurar el nodo de entrada para analizar y validar totalmente el mensaje.

Sin embargo, tenga en cuenta que esto sólo se aplica a mensajes predefinidos, es decir MRM o IDOC.

Si el nodo de entrada se configura de este modo, se garantiza lo siguiente en el caso de que el mensaje de entrada no se pueda analizar satisfactoriamente:
  • El mensaje de entrada no emerge nunca del terminal de salida normal del nodo (va al terminal de anomalías).
  • 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 tratar un mensaje anómalo, conecte un flujo de lógica simple al terminal de anomalías.

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 queda 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:
  1. La base de datos no funciona en absoluto (por ejemplo, está fuera de línea).
  2. La base de datos funciona pero rechaza la petición (por ejemplo, se produce una contención de bloque).
  3. La base de datos funciona pero lo que se solicita que haga es imposible (por ejemplo, leer en una tabla no existente).

Si necesita algo mejor que el manejo de errores por omisión, el primer paso es utilizar un manejador (consulte el apartado Sentencia DECLARE HANDLER) para interceptar la excepción. El manejador puede determinar la naturaleza de la anomalía a partir del estado de SQL devuelto por la base de datos.

La base de datos no funciona
Si una base de datos no funciona en absoluto y es esencial para el proceso de mensajes, es probable que no pueda hacer gran cosa. En este caso, es posible que el manejador pueda realizar alguna de las acciones siguientes, después de determinar la causa:
  • Utilizar la sentencia RESIGNAL para volver a generar el error original, permitiendo de este modo que el manejador de errores por omisión 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. Dado que el manejador absorbe la excepción, se confirman los cambios en otras bases de datos o las grabaciones en colas.

La base de datos rechaza la petición
Cuando se produce una contención de bloqueo, la situación es similar al caso "La base de datos no funciona". Esto se debe a que la base de datos habrá restituido todos los cambios de base de datos que se hayan 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, es probable que no haya ninguna estrategia mejor que la del manejo de errores por omisión, 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 realice 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, es probable otra vez que no haya ninguna estrategia mejor que la del manejo de errores por omisión, excepto posiblemente registrar el error o pasar el mensaje a una cola especial.
No obstante, es posible que muchos otros errores se manejen satisfactoriamente. Por ejemplo, un intento de inserción de una fila puede fallar porque ya existe dicha fila y la nueva fila sería un duplicado. O un intento de actualización de 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 error, la propiedad de nodo "tratar los avisos como errores" debe establecerse en verdadera. Éste no es el valor por omisión.

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

Inicio del cambioLos errores que se producen en los nodos de salida MQ indican la naturaleza del error en el estado de SQL y proporcionan información adicional en la variable de error nativo de SQL. De este modo, si se necesita algo mejor que el manejo de errores por omisión, el primer paso es utilizar un manejador (consulte Sentencia DECLARE HANDLER) para interceptar la excepción. Un manejador de este tipo sólo suele encargarse de una sola sentencia PROPAGATE. Fin del cambio

Utilización de la lógica propia para manejar otros errores

Además de los errores descritos más arriba, se pueden producir 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 mensaje puede fallar debido a una restricción de tipo. El intermediario ofrece dos estrategias de programación para tratarlos.
  1. El error produce una excepción que se maneja o se deja para restituir la transacción.
  2. La anomalía se registra como un valor especial que se prueba para más adelante.

En la ausencia de una restricción de tipo, un intento de acceder a un campo de mensaje no existente produce el valor nulo. Los valores nulos se propagan mediante las expresiones, haciendo que el resultado sea nulo. De este modo, si una expresión, por compleja que sea, no devuelve un valor nulo, sabrá que todos los valores que necesitaba para calcular el resultado no eran nulos.

Las expresiones de transformación CAST pueden tener una cláusula por omisión. Si hay una cláusula por omisión, las transformaciones CAST fallan silenciosamente; en lugar de generar una excepción, simplemente devuelven el valor por omisión. El valor por omisión 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). Nulo puede ser especialmente adecuado, porque es un valor que es diferente de todos los demás y que se propagará mediante las expresiones sin ninguna posibilidad de que la condición de error quede enmascarada.

Manejo de errores en otros nodos

Es posible que las excepciones que se producen en otros nodos (es decir, en sentido descendente de una sentencia PROPAGATE) las capten de forma normal los manejadores. Sin embargo, el manejo inteligente de dichos errores plantea el problema especial que supone el hecho de que, dado que había otro nodo implicado en el error original, es muy probable que otro nodo y no necesariamente el que ha originado la excepción esté implicado en el manejo del mismo.

Para ayudar en estas situaciones los nodos de base de datos y de cálculo tiene cuatro terminales nuevos denominados out1, out2, out3 y out4. Además, se ha ampliado la sintaxis de la Sentencia PROPAGATE para incluir cláusulas de expresión de destino, de origen de mensajes y de control para proporcionar más control sobre estos terminales adicionales.

Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Su opinión
Copyright IBM Corporation 1999, 2006 Última actualización: 22/08/2006
ac17140_