Istruzione BEGIN ... END

L'istruzione BEGIN ... END fornisce alle istruzioni definite all'interno delle parole chiave BEGIN ed END lo stato di una singola istruzione.

Ciò consente alle istruzioni contenute di:
  • Essere il contenuto di una funzione o di una procedura
  • Far gestire le proprie eccezioni da un programma di gestione
  • Fare arrestare la propria esecuzione da un'istruzione LEAVE

SINTASSI

La seconda Label può essere presente solo se è presente la prima Label. Se sono presenti entrambe, devono essere identiche. Due o più istruzioni con etichetta allo stesso livello possono avere la stessa etichetta, ma ciò annulla parzialmente il vantaggio della seconda etichetta. Il vantaggio è che le etichette associano in modo chiaro ed accurato ciascuna istruzione END con la relativa istruzione BEGIN. Tuttavia, un'istruzione con etichetta nidificata all'interno di Statements non può avere la stessa etichetta, perché ciò renderebbe ambiguo il funzionamento delle istruzioni ITERATE e LEAVE.

Ambito delle variabili

Un nuovo ambito della variabile locale viene aperto immediatamente dopo l'istruzione BEGIN iniziale e, quindi, tutte le variabili dichiarate all'interno di tale istruzione vanno fuori dall'ambito quando viene raggiunta l'istruzione END finale. Se una variabile locale ha lo stesso nome di una variabile esistente, tutti i riferimenti a tale nome inseriti dopo la dichiarazione accedono alla variabile locale. Ad esempio:
DECLARE Variable1 CHAR 'Existing variable';

-- A reference to Variable1 here returns 'Existing variable'

BEGIN
  -- A reference to Variable1 here returns 'Existing variable'

  DECLARE Variable1 CHAR 'Local variable';  -- Perfectly legal even though 
the name is the same

  -- A reference to Variable1 here returns 'Local variable'
END;

ATOMIC

Se è specificato ATOMIC, solo un'istanza di un flusso di messaggi (un thread) può eseguire le istruzioni di un'istruzione BEGIN ATOMIC... END specifica (identificata dal proprio schema e dalla propria etichetta), in qualsiasi momento. Se non è presente alcuna etichetta, il funzionamento è identico a quello nel caso in cui sia stata specificata un'etichetta di lunghezza zero.

La struttura BEGIN ATOMIC è utile quando è necessario apportare un numero di modifiche ad una variabile condivisa ed è importante per evitare che altre istanze vedano gli stati intermedi dei dati. Considerare il seguente esempio di codice:
CREATE PROCEDURE WtiteSharedVariable1(IN NewValue CHARACTER)
SharedVariableMutex1 : BEGIN ATOMIC
  -- Set new value into shared variable
END;

CREATE FUNCTION ReadSharedVariable1() RETURNS CHARACTER
SharedVariableMutex1 : BEGIN ATOMIC
  DECLARE Value CHARACTER;
  -- Get value from shared variable
  RETURN Value;
END;
Nell'ultimo esempio, si suppone che la procedura WriteSharedVariable1 e la funzione ReadSharedVariable1 siano nello stesso schema e che vengano utilizzate dai nodi all'interno dello stesso flusso. Tuttavia, non è importante se la procedura e la funzione sono contenute all'interno di moduli o se sono utilizzate all'interno dello stesso nodo o di nodi differenti. Il broker assicura che, in qualsiasi momento, solo un thread esegue le istruzioni all'interno delle sezioni atomic. Ciò assicura che, ad esempio, due scritture contemporanee oppure una scrittura ed una lettura contemporanee vengano eseguite in modo seriale. Notare che:
  • La serializzazione è limitata al flusso. Due flussi che utilizzano istruzioni BEGIN ATOMIC... END con lo stesso schema e la stessa etichetta possono essere eseguiti contemporaneamente. Per questo motivo, più istanze all'interno di un flusso e più copie di un flusso non sono equivalenti.
  • La serializzazione è limitata dallo schema e dall'etichetta. Le istruzioni Atomic BEGIN ... END specificate in schemi diversi o con etichette diverse non interagiscono tra loro.
Nota: E' possibile considerare tale concetto in modo differente. Per ciascuna combinazione di flusso di messaggi, schema ed etichetta, il broker dispone di un mutex che impedisce l'accesso contemporaneo alle istruzioni associate a tale mutex.

Non nidificare istruzioni BEGIN ATOMIC... END in modo diretto o indiretto, perché potrebbero verificarsi "conseguenze fatali". Per questo motivo, non utilizzare un'istruzione PROPAGATE dall'interno di un blocco atomic.

Non è necessario utilizzare la struttura BEGIN ATOMIC in flussi che non verranno mai distribuiti con più di una istanza (ma potrebbe essere imprudente lasciare questa opzione al caso). Inoltre, non è necessario utilizzare la struttura BEGIN ATOMIC in letture e scritture su variabili condivise. Il broker, per sicurezza, scrive sempre un nuovo valore in una variabile condivisa e legge sempre l'ultimo valore da una variabile condivisa. ATOMIC è richiesta solo quando l'applicazione è sensibile alla visualizzazione dei risultati intermedi.

Considerare il seguente esempio:
DECLARE LastOrderDate SHARED DATE;
...
SET LastOrderDate = CURRENT_DATE;
...
SET OutputRoot.XMLNSC.Data.Orders.Order[1].Date = LastOrderDate;
In questo esempio, si suppone che un thread stia aggiornando periodicamente LastOrderDate e che un altro thread ki stia leggendo periodicamnte. Non è necessario utilizzare ATOMIC, perchè la seconda istruzione SET legge sempre un valore valido. Se l'aggiornamento e la lettura vengono eseguite in un breve intervallo di tempo, anche se non è sicuro che venga letto il vecchio o il nuovo valore, è sempre uno o l'altro. Il risultato non sarà mai non corretto.
Considerare ora il seguente esempio:
DECLARE Count SHARED INT;
...
SET Count = Count + 1;
In questo esempio, si suppone che diversi thread stiano eseguendo periodicamente l'istruzione SET. In questo caso è necessario utilizzare ATOMIC, perché due thread potrebbero leggere Count nello stesso istante e ricevere lo stesso valore. Entrambi i thread eseguono l'addizione e memorizzano lo stesso valore. Il risultato finale, quindi, è N+1 e non N+2.

Il broker non fornisce automaticamente il blocco di livello superiore (ad esempio, un blocco di tutta l'istruzione SET), perché questo tipo di blocco potrebbe comportare "conseguenze fatali".

Suggerimento

E' possibile considerare l'istruzione BEGIN ... END come una struttura di loop, che esegue sempre il loop una volta. L'effetto su un'istruzione ITERATE o LEAVE nidificata all'interno di un'istruzione BEGIN ... END è quindi quello previsto: il controllo viene trasferito all'istruzione che segue END. L'utilizzo di ITERATE o LEAVE all'interno di un'istruzione BEGIN ... END è utile nei casi in cui esiste una lunga serie di calcoli che deve essere annullata, perché è stato raggiunto un risultato definito oppure perché si è verificato un errore.

Concetti correlati
Panoramica di ESQL
Attività correlate
Sviluppo di ESQL
Riferimenti correlati
Diagrammi di sintassi: tipi disponibili
Istruzioni ESQL
Informazioni particolari | Marchi | Download | Libreria | Supporto | Commenti
Copyright IBM Corporation 1999, 2006 Ultimo aggiornamento: ago 17, 2006
ak04940_