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.
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.
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.
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.
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.
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:
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 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.
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.
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.
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.
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 acción de 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).
Si desea que una actualización de cero filas se indique como error, deberá establecer la propiedad Tratar los avisos como errores en el nodo en true, que no es el valor predeterminado.
Los errores que se producen en nodos MQOutput indican la naturaleza del error en el estado 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.
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.
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.