Codificando o ESQL para Tratar Erros

Apresentação

Ao processar mensagens nos fluxos de mensagens, podem ocorrer erros devido a:
  1. Causas externas. Por exemplo, a mensagem que chega é sintaticamente inválida, um banco de dados utilizado pelo fluxo foi encerrado ou a fonte de alimentação para a máquina na qual o intermediário está em execução falhou.
  2. Causas internas. Por exemplo, uma tentativa de inserir uma linha em uma tabela de banco de dados falha devido a uma verificação de restrição ou uma cadeia de caracteres lida a partir de um banco de dados não pode ser convertida em um número, porque contém caracteres alfabéticos.

    Os erros internos podem ser causados por programas que armazenam dados inválidos no banco de dados ou por uma falha na lógica de um fluxo.

O designer do fluxo de mensagens deve considerar seriamente os erros e decidir como eles devem ser manipulados.

Utilizando a Identificação de Erros Padrão

A estratégia mais simples para manipular erros ESQL é não fazer nada e utilizar o comportamento padrão do intermediário. O comportamento padrão é interromper o processamento da mensagem com falha e prosseguir para a próxima mensagem. Os nós de entrada e de saída fornecem opções para controlar exatamente o que acontece quando o processamento é interrompido.

Se os nós de entrada e de saída estiverem configurados para o modo transacional, o intermediário restaurará o estado anterior para a mensagem que está sendo processada:
  1. A mensagem de entrada que aparentemente foi obtida da fila de entrada é retornada.
  2. As mensagens de saída que o fluxo aparentemente gravou nas filas de saída são descartadas.
Se os nós de entrada e de saída não estiverem configurados para o modo transacional:
  1. A mensagem de entrada obtida da fila de entrada não é retornada.
  2. As mensagens de saída que o fluxo gravou em filas de saída permanecem lá.

Cada uma destas estratégias tem suas vantagens. O modelo transacional preserva a consistência de dados, enquanto o modelo não transacional aumenta a continuidade do processamento de mensagens. Lembre-se de que no modelo transacional a mensagem de entrada com falha é retornada à fila de entrada e o intermediário tentará processá-la novamente. O resultado mais provável disso é que a mensagem continuará falhando até que seja alcançado o limite de nova tentativa e, neste ponto, ela é colocada em uma fila de devoluções. A razão para a falha ao processar a mensagem é registrada no registro de eventos do sistema (Windows) ou no syslog (UNIX). Portanto, a mensagem com falha suspende o processamento de mensagens válidas subseqüentes por um momento e, em seguida, é deixada sem ser processada pelo intermediário.

A maioria dos bancos de dados operam de forma transacional, portanto, todas as alterações feitas em tabelas de banco de dados serão confirmadas, se o processamento da mensagem for bem-sucedido e ocorrerá o rollback se ele falhar, mantendo, assim, a integridade de dados. Uma exceção para isso é que, se o próprio intermediário ou um banco de dados falhar. (Por exemplo, a energia para as máquinas nas quais eles estão em execução pode ser interrompida). Nestes casos, é possível que as alterações em alguns bancos de dados sejam confirmadas e as alterações em outros não; ou que as alterações dos bancos de dados sejam confirmadas mas as mensagens de entrada e de saída não sejam. Se estas possibilidades são motivos de preocupação, o fluxo deverá ser coordenado e os bancos de dados envolvidos configurados para esta maneira de funcionamento.

Utilizando a Manipulação de Erro Customizada

Aqui estão algumas dicas gerais sobre como criar rotinas de tratamento de erros customizadas:
  1. Se você precisar de algo melhor do que a manipulação de erro padrão, a primeira etapa será utilizar uma rotina de tratamento (consulte Instrução DECLARE HANDLER). Crie uma rotina de tratamento por nó, para interceptar todas as possíveis exceções (ou quantas exceções puderem ser previstas).
  2. Tendo interceptado um erro, a rotina de tratamento de erros pode utilizar qualquer lógica apropriada para tratá-lo. Como alternativa, ela pode utilizar uma instrução THROW ou um nó para criar uma exceção, que pode ser manipulada de forma superior na lógica do fluxo ou mesmo alcançar o nó input, causando o rollback da transação. Consulte Lançando uma Exceção.
  3. Se um nó emitir uma exceção que não seja capturada pela rotina de tratamento, o fluxo será desviado para o terminal de falha, se houver um conectado ou manipulado pela manipulação de erro se não estiver conectado.

    Utilize terminais de falha para captar erros não manipulados. Conecte um fluxo de lógica simples ao terminal de falha. Este fluxo de lógica pode consistir em um banco de dados ou um nó Compute que grava um registro de log em um banco de dados (possivelmente incluindo o fluxo de bits da mensagem) ou grava um registro no registro de eventos. Ele também pode conter um nó de saída que grava a mensagem em uma fila especial.

    A árvore de exceções completa é transmitida para qualquer nó conectado a um terminal de falha. (A árvore de exceções está descrita em Estrutura em Árvore ExceptionList).

  4. Suas rotinas de tratamento de erros são responsáveis por registrar cada erro em um local apropriado, como o registro de eventos do sistema.

Para obter uma discussão detalhada das opções que podem ser utilizadas para processar erros em um fluxo de mensagens, consulte Tratando Erros em Fluxos de Mensagens. Os tópicos a seguir fornecem exemplos específicos do que pode ser feito:

Codificando para Detectar Erros

As seções a seguir supõem que é o intermediário que detecta o erro. No entanto, é possível que a lógica do fluxo detecte um erro. Por exemplo, ao codificar a lógica do fluxo, você pode utilizar:
  • Instruções IF inseridas especificamente para detectar situações que não devem ocorrer
  • A cláusula ELSE de uma expressão ou instrução case para interromper rotas por meio do código que não deve ser possível
Como exemplo de um erro detectado por uma lógica de fluxo, considere um campo que tenha um intervalo de possíveis valores inteiros indicando o tipo de mensagem. Neste caso, não seria recomendável esperar para ver o que aconteceria se tivesse que chegar uma mensagem na qual o valor do campo não correspondesse a nenhum tipo de mensagem conhecido. Uma forma de isso ocorrer é se o sistema tiver recebido upgrade para suportar tipos extras de mensagens, mas uma parte do sistema não tiver recebido upgrade.

Utilizando sua Própria Lógica para Manipular Mensagens de Entrada Inválidas

As mensagens de entrada sintaticamente inválidas (e mensagens de entrada que parecem inválidas devido a informações de formato de mensagem errôneo) são difíceis de lidar, porque o intermediário não sabe o que a mensagem contém. Provavelmente, a melhor maneira de se lidar com elas é configurar o nó input para analisar e validar totalmente a mensagem.

Observe, no entanto, que isso se aplica somente a mensagens predefinidas, ou seja, MRM ou IDOC.

Se o nó input for configurado dessa forma, o seguinte é garantido se a mensagem de entrada não puder ser analisada com êxito.
  • A mensagem de entrada nunca é originada no terminal de saída normal do nó (ela vai para o terminal de falha).
  • A mensagem de entrada nunca entra na parte principal do fluxo de mensagens.
  • A mensagem de entrada nunca causa nenhuma atualização do banco de dados.
  • Nenhuma mensagem é gravada em nenhuma das filas de saída.

Para lidar com uma mensagem em falha, conecte a um fluxo lógico simples para o terminal de falha.

A única desvantagem desta estratégia é que, se o fluxo normal não exigir acesso a todos os campos da mensagem, o ato de forçar a análise completa da mensagem afetará o desempenho.

Utilizando sua Própria Lógica para Manipular Erros do Banco de Dados

Os erros do banco de dados estão em três categorias:
  1. O banco de dados não está funcionando (por exemplo, está off-line).
  2. O banco de dados está funcionando mas rejeita seu pedido (por exemplo, ocorre uma contenção de bloqueio).
  3. O banco de dados está funcionando, mas é impossível fazer o que você solicitou (por exemplo, fazer leitura a partir de uma tabela não existente).

Se você precisar de algo melhor do que a manipulação de erro padrão, a primeira etapa será utilizar uma rotina de tratamento (consulte Instrução DECLARE HANDLER) para interceptar a exceção. A rotina de tratamento pode determinar a natureza da falha a partir do estado de SQL retornado pelo banco de dados.

O banco de dados não está funcionando
Se um banco de dados não estiver funcionando e ele for essencial para o processamento de mensagens, provavelmente, não haverá muito a ser feito. Neste caso, a rotina de tratamento tendo determinado a causa, pode executar um dos seguintes procedimentos:
  • Utilizar a instrução RESIGNAL para emitir novamente o erro original permitindo, assim, que a rotina de tratamento de erros padrão tome o controle.
  • Utilizar um banco de dados diferente.
  • Gravar a mensagem em uma fila de saída especial.

    No entanto, tome cuidado com este tipo de estratégia. Como a rotina de tratamento absorve a exceção, as alterações em outros bancos de dados ou gravações em filas são confirmadas.

O banco de dados rejeita seu pedido
A situação quando ocorre uma contenção de bloqueio é semelhante ao caso "O banco de dados não está funcionando". Isto ocorre porque o banco de dados efetuou backout de todas as alterações do banco de dados feitas na mensagem atual, não apenas do pedido com falha. Portanto, a menos que você tenha certeza de que esta era a única atualização, é improvável que exista alguma estratégia melhor do que a manipulação de erro padrão, exceto um possível registro do erro ou transmissão da mensagem para uma fila especial.
Pedidos impossíveis
O caso em que o banco de dados está funcionando mas é impossível fazer o que você solicitou cobre uma grande variedade de problemas.
Se, como no exemplo, o banco de dados simplesmente não possui uma tabela do nome esperado pelo fluxo, novamente será improvável que exista uma estratégia melhor do que a manipulação de erro padrão, exceto um possível registro do erro ou transmissão da mensagem para uma fila especial.
No entanto, muitos outros erros podem ser manipulados com êxito. Por exemplo, uma tentativa de inserir uma linha pode falhar, porque já existe esta linha e a nova linha seria uma duplicata. Ou uma tentativa de atualizar uma linha pode falhar, porque não existe esta linha (ou seja, a atualização atualizou zero linhas). Nestes casos, a rotina de tratamento pode incorporar qualquer lógica cabível. Ela pode inserir a linha ausente ou utilizar uma existente (provavelmente certificando-se de que os valores dela sejam apropriados).
Nota: Para que uma atualização de zero linhas seja relatada como um erro, a propriedade do nó "tratar avisos como erros" deve ser configurada como true. Esta não é a configuração padrão.

Utilizando sua Própria Lógica para Manipular Erros em Nós de Saída

Início da mudançaOs erros que ocorrem nos nós de saída do MQ relatam a natureza do erro no estado SQL e fornecem informações adicionais na variável Erro nativo de SQL. Portanto, se for requerido algo melhor do que a manipulação de erro padrão, a primeira etapa será utilizar uma rotina de tratamento (consulte Instrução DECLARE HANDLER) para interceptar a exceção. Esse manipulador normalmente envolve somente uma única instrução PROPAGATE. Fim da mudança

Utilizando sua Própria Lógica para Manipular Outros Erros

Além dos assuntos abordados acima, podem ocorrer vários outros erros. Por exemplo, um cálculo aritmético pode estourar, um lançamento pode falhar devido à inadequação dos dados ou um acesso a um campo de mensagem pode falhar devido a uma restrição de tipo. O intermediário oferece duas estratégias de programação para lidar com eles.
  1. O erro causa uma exceção que é manipulada ou permanece para efetuar rollback da transação.
  2. A falha é registrada como um valor especial que será testado posteriormente.

Na ausência de uma restrição de tipo, uma tentativa de acesso a um campo de mensagem não existente pode resultar no valor nulo. Os valores nulos são propagados tornando o resultado nulo. Portanto, se uma expressão, ainda que complexa, não retornar um valor nulo, você saberá que todos os valores utilizados por ela para calcular seu resultado não eram nulos.

As expressões de lançamento podem ter uma cláusula padrão. Se houver uma cláusula padrão, os lançamentos falharão de maneira silenciosa; em vez de emitir uma exceção, eles apenas retornam o valor padrão. O valor padrão pode ser um número inócuo (por exemplo, zero para um inteiro) ou um valor que seja claramente inválido no contexto (por exemplo, -1 para um número de cliente). O nulo pode ser especificamente adequado, porque é um valor diferente de todos os outros e que será propagado por meio de expressões sem nenhuma possibilidade de a condição de erro estar sendo mascarada.

Manipulando Erros em Outros Nós

Exceções ocorridas em outros nós (ou seja, recebimento de dados de uma instrução PROPAGATE) podem ser captadas por rotinas de tratamento de maneira normal. Manipular tais erros de forma inteligente, no entanto, sugere o problema especial de que, como outro nó estava envolvido no erro original, outro nó, e não necessariamente o originador da exceção, tem grande probabilidade de estar envolvido em sua manipulação.

Para ajudar nessas situações, os nós database e compute têm quatro novos terminais chamados out1, out2, out3 e out4. Além disso, a sintaxe do Instrução PROPAGATE foi estendida para incluir expressão de destino, origem da mensagem e cláusulas de controle para fornecer maior controle sobre esses terminais extras.

Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback
Direitos Autorais IBM Corporation 1999, 2006 Última Atualização: 1 Sep 2006
ac17140_