Codifica ESQL per gestire gli errori

Introduzione

Durante l'elaborazione dei messaggi nei flussi di messaggi, gli errori possono essere dovuti a:
  1. Cause esterne. Ad esempio, il messaggio in entrata è sintatticamente non valido, un database utilizzato dal flusso è stato disattivato o l'alimentazione della macchina su cui è in esecuzione il broker non funziona.
  2. Cause interne. Ad esempio, un tentativo di inserire una riga in una tabella di database non riesce a causa di un controllo del vincolo o una stringa di caratteri letta da un database non può essere convertita in un numero perché contiene caratteri alfabetici.

    Gli errori interni possono essere causati da programmi che memorizzano dati non validi nel database o da un difetto nella logica di un flusso.

Chi progetta il flusso di messaggi deve prestare particolare attenzione agli errori e decidere come vadano gestiti.

Utilizzo della gestione errori predefinita

La strategia più semplice per gestire gli errori ESQL è quella di non fare niente e utilizzare il funzionamento predefinito del broker. Tale funzionamento consiste nell'interrompere l'elaborazione del messaggio che ha dato esito negativo e procedere con il messaggio successivo. I nodi di input e di output forniscono opzioni per controllare esattamente cosa accade quando si interrompe l'elaborazione.

Se i nodi di input e di output sono impostati sul modo transazionale, il broker ripristina lo stato precedente all'elaborazione del messaggio:
  1. Il messaggio di input che è stato evidentemente estratto dalla coda di input viene inserito di nuovo nella sua ubicazione.
  2. Tutti i messaggi di output che il flusso ha evidentemente scritto nelle code di output sono eliminati.
Se i nodi di input e di output non sono impostati sul modo transazionale:
  1. Il messaggio di input estratto dalla coda di input non viene reinserito nella sua ubicazione.
  2. Tutti i messaggi di output che il flusso ha scritto nelle code di output restano in tali code.

Ciascuna di queste strategie ha i suoi vantaggi. Il modello transazionale conserva la coerenza dei dati, mentre il modello non-transazionale massimizza la continuità dell'elaborazione del messaggio. Ricordare che nel modello transazionale il messaggio di input in errore viene reinserito nella coda di input e il broker tenterà di elaborarlo di nuovo. Il risultato più probabile di questa operazione è che il messaggio continui ad avere esito negativo fino a quando non si raggiunge il limite di nuovi tentativi e a quel punto sarà inserito in una coda di messaggi non recapitati. Il motivo per cui non è stato possibile elaborare il messaggio viene registrato nel registro eventi del sistema (Windows) o syslog (UNIX). Quindi il messaggio non riuscito tiene in sospeso per un certo periodo di tempo l'elaborazione dei messaggi validi successivi e poi il broker lascia che rimanga non elaborato.

La maggior parte dei database funziona in modalità transazionale, in modo che tutte le modifiche effettuate sulle tabelle di database siano sottoposte a commit, se l'elaborazione del messaggio ha esito positivo e a rollback se ha esito negativo, mantenendo quindi l'integrità dei dati. Fa eccezione il caso in cui il broker stesso o un database, abbia esito negativo. (Ad esempio, l'alimentazione delle macchine su cui sono in esecuzione potrebbe venire interrotta.) In questi casi, è possibile che le modifiche in alcuni database siano sottoposte a commit e le modifiche in altri database no; o che le modifiche del database siano sottoposte a commit ma i messaggi di input e di output non lo siano. Se si verifica questa situazione, il flusso dovrebbe essere coordinato e i database interessati configurati per questa modalità di funzionamento.

Utilizzo della gestione errori personalizzata

Qui di seguito sono indicati alcuni suggerimenti di carattere generale sulla creazione di programmi di gestione errori personalizzati:
  1. Se è necessaria una gestione errori migliore rispetto a quella predefinita, il primo passo è quello di utilizzare un programma di gestione errori (consultare la sezione Istruzione DECLARE HANDLER). Creare un programma di gestione per nodo, per intercettare tutte le possibili eccezioni (o tante eccezioni quante se ne possono prevedere).
  2. Una volta intercettato un errore, il programma di gestione errori può utilizzare qualsiasi logica appropriata per gestirlo. In alternativa, può utilizzare un'istruzione o un nodo THROW per creare un'eccezione, che potrebbe essere gestita ad un livello più elevato nella logica del flusso o addirittura raggiungere il nodo di input, avendo come risultato il rollback della transazione. Consultare Generazione di un'eccezione.
  3. Se un nodo genera un'eccezione che non viene rilevata dal programma di gestione, il flusso viene dirottato al terminale failure, se collegato o gestito dalla gestione errori predefinita in caso contrario.

    Utilizzare i terminali failure per rilevare gli errori non gestiti. Collegare al terminale failure un flusso logico semplice. Tale flusso logico potrebbe consistere in un database o nodo Compute che scrive un record della registrazione in un database (possibilmente includendo il flusso di bit del messaggio) o scrive un record nella registrazione eventi. Esso potrebbe anche contenere un nodo di output che scrive il messaggio in una coda speciale.

    La struttura ad albero delle eccezioni completa viene trasmessa a qualunque nodo connesso a un terminale failure. (La struttura ad albero delle eccezioni è descritta in Struttura ad albero ExceptionList.)

  4. I programmi di gestione errori sono responsabili della registrazione di ogni errore nell'ubicazione appropriata, come una registrazione eventi di sistema.

Per una spiegazione dettagliata delle opzioni che è possibile utilizzare per elaborare gli errori in un flusso di messaggi, consultare Gestione degli errori nei flussi di messaggi. I seguenti argomenti forniscono esempi di cosa è possibile fare:

Codifica per rilevare gli errori

Le seguenti sezioni presuppongono che sia il broker a rilevare l'errore. E' piuttosto probabile, tuttavia, che la logica del flusso rilevi un errore. Ad esempio, quando si codifica la logica del flusso si potrebbero utilizzare:
  • Le istruzioni IF inserite in modo specifico per rilevare situazioni che non dovrebbero verificarsi
  • La clausola ELSE di un'espressione o istruzione Case maiuscolo/minuscolo o istruzione per individuare instradamenti non possibili attraverso il codice
Come esempio di un errore rilevato dalla logica del flusso, prendere in considerazione un campo con un intervallo di possibili valori interi che indicano il tipo di messaggio. In una simile evenienza è sconsigliabile lasciare al caso la gestione di un eventuale messaggio in cui il valore del campo non corrisponda ad alcun tipo di messaggio conosciuto. Questo potrebbe succedere se, ad esempio, il sistema è aggiornato per supportare tipi di messaggi supplementari ma una parte del sistema non è aggiornata.

Utilizzo della logica per gestire i messaggi di input che non sono validi

E' difficile gestire i messaggi di input sintatticamente non validi (e i messaggi di input che sembrano non validi a causa di erronee informazioni sul formato del messaggio), poiché il broker non ha idea di cosa contenga il messaggio. Probabilmente il modo migliore per gestirli è quello di configurare il nodo di input per analizzare completamente e convalidare il messaggio.

Si noti, tuttavia, che questo si applica solo ai messaggi predefiniti, cioè MRM o IDOC.

Se il nodo di input è configurato in questo modo, quanto segue è garantito se il messaggio di input non può essere analizzato con esito positivo:
  • Il messaggio di input non esce mai dal terminale di output normale del nodo (va al terminale failure).
  • Il messaggio di input non entra mai nella parte principale del flusso di messaggi.
  • Il messaggio di input non causa mai alcun aggiornamento del database.
  • Non è scritto alcun messaggio in alcuna coda di output.

Per gestire un messaggio non riuscito, connettere un flusso logico semplice al terminale failure.

Il solo svantaggio di questa strategia è che, se il flusso normale non richiede accesso a tutti i campi del messaggio, la forzatura dell'analisi completa del messaggio ha effetti sulle prestazioni.

Utilizzo della propria logica per gestire gli errori del database

Gli errori del database rientrano in tre categorie:
  1. Il database non funziona affatto (ad esempio, non è in linea).
  2. Il database sta funzionando ma non accetta la richiesta (ad esempio, si verifica un conflitto di blocchi).
  3. Il database sta funzionando ma ciò che si richiede di eseguire è impossibile (ad esempio, leggere da tabelle non esistenti).

Se è necessaria una gestione errori migliore rispetto a quella predefinita, il primo passo è quello di utilizzare un programma di gestione errori (consultare la sezione Istruzione DECLARE HANDLER) per intercettare l'eccezione. Il programma di gestione può stabilire la natura del problema dallo stato SQL restituito dal database.

Il database non funziona
Se un database non funziona affatto ed è fondamentale per l'elaborazione dei messaggi, probabilmente non c'è molto da fare. In questo caso il programma di gestione, avendo stabilito la causa, potrebbe effettuare quanto segue:
  • Utilizzare l'istruzione RESIGNAL per generare nuovamente l'errore originale, consentendo quindi al programma di gestione errori predefinito di intervenire.
  • Utilizzare un diverso database.
  • Scrivere il messaggio in una coda di output speciale.

    Tuttavia, fare attenzione con questo tipo di strategia. Poiché il programma di gestione assimila l'eccezione, tutte le modifiche ad altri database o le scritture nelle code sottoposte a commit.

Il database non accetta la richiesta
La situazione in cui si verifica un conflitto di blocchi è simile al caso "Il database non funziona". Questo perché il database avrà eseguito il ripristino allo stato precedente di tutte le modifiche ad esso relative eseguite per il messaggio corrente, non solo della richiesta che ha avuto esito negativo. Quindi, a meno di non essere sicuri che questo sia l'unico aggiornamento, è poco probabile che ci sia una strategia migliore della gestione errori predefinita, tranne forse la registrazione dell'errore o la trasmissione del messaggio a una coda speciale.
Richieste impossibili
Il caso in cui il database sta funzionando ma ciò che si richiede di eseguire è impossibile, riguarda un'ampia gamma di problemi.
Se, ad esempio, il database semplicemente non ha una tabella con il nome previsto dal flusso, è di nuovo poco probabile che esista una strategia migliore della gestione errori predefinita, tranne forse la registrazione dell'errore o la trasmissione del messaggio a una coda speciale.
Comunque, sono molti gli errori che si possono gestire con esito positivo. Ad esempio, un tentativo di inserire una riga potrebbe avere esito negativo poiché esiste già tale riga e quella nuova sarebbe un duplicato. O un tentativo di aggiornare una riga potrebbe avere esito negativo poiché tale riga non esiste (cioè, l'aggiornamento ha aggiornato zero righe). In questi casi, il programma di gestione può incorporare qualsiasi logica si ritenga appropriata. Esso potrebbe inserire la riga mancante o utilizzare quella esistente (possibilmente accertandosi che i valori in essa siano idonei).
Nota: perché un aggiornamento di zero righe venga notificato come errore, la proprietà del nodo "valuta le avvertenze come errori" deve essere impostata su true. Questa non è l'impostazione predefinita.

Utilizzo della propria logica per gestire gli errori nei nodi di output

Inizio modificaGli errori che si verificano nei nodi di output MQ riportano la natura dell'errore nello stato SQL e forniscono ulteriori informazioni nella variabile Errore nativo SQL. Quindi, se è necessaria una gestione errori migliore rispetto a quella predefinita, il primo passo è quello di utilizzare un programma di gestione errori (consultare la sezione Istruzione DECLARE HANDLER) per intercettare l'eccezione. Questo programma include di solito un'unica istruzione PROPAGATE. Fine modifica

Utilizzo della propria logica per gestire altri errori

Oltre a quelli affrontati prima, si possono verificare diversi altri errori. Ad esempio, potrebbe verificarsi che un calcolo aritmetico superi il valore consentito, che un cast abbia esito negativo a causa della non idoneità dei dati o che un accesso a un campo del messaggio abbia esito negativo a causa di un vincolo relativo al tipo. Il broker offre due strategie di programmazione per gestire queste situazioni.
  1. L'errore causa un'eccezione che viene gestita o si lascia che porti al rollback della transazione.
  2. L'errore viene registrato come un valore speciale di cui è eseguito il test in un momento successivo.

In assenza di un vincolo relativo al tipo, un tentativo di accedere a un campo di messaggio non esistente ha come risultato il valore null. I valori null si trasmettono nelle espressioni, rendendo il risultato null. Quindi, se un'espressione, per quanto complessa, non restituisce un valore null, se ne deduce che tutti i valori necessari per calcolarne il risultato non erano null.

Le espressioni relative al cast possono avere una clausola predefinita. Se esiste una clausola predefinita, i cast hanno esito negativo senza che nulla accada; invece di generare un'eccezione, restituiscono semplicemente il valore predefinito. Il valore predefinito potrebbe essere un numero innocuo (ad esempio, zero per un numero intero) o un valore che chiaramente non è valido nel contesto (ad esempio, -1 per un numero cliente). Il valore null potrebbe essere particolarmente adatto, poiché è un valore che si differenzia da tutti gli altri e che si trasmetterà nelle espressioni senza alcuna possibilità che la condizione di errore venga nascosta.

Gestione degli errori in altri nodi

Le eccezioni che si verificano in altri nodi (cioè, dopo l'elaborazione di un'istruzione PROPAGATE) potrebbero essere rilevate dai programmi di gestione nel modo usuale. La gestione intelligente di tali errori, tuttavia, pone il problema particolare che, poiché nell'errore originale era coinvolto un altro nodo, un altro nodo e non necessariamente quello all'origine dell'eccezione, sarà molto probabilmente coinvolto nella sua gestione.

Come supporto in queste situazioni il database e i nodi Compute dispongono di quattro nuovi terminali chiamati out1, out2, out3 e out4. Inoltre, la sintassi dell'Istruzione PROPAGATE è stata estesa per includere l'espressione di destinazione, l'origine del messaggio e le clausole di controllo per fornire maggiore controllo su questi terminali supplementari.

Informazioni particolari | Marchi | Download | Libreria | Supporto | Commenti
Copyright IBM Corporation 1999, 2006 Ultimo aggiornamento: ago 17, 2006
ac17140_