BEGIN ... END-Anweisung

Die BEGIN ... END-Anweisung (Anfang ... Ende-Anweisung) gibt den innerhalb der Schlüsselwörter BEGIN und END definierten Anweisungen den Status einer einzelnen Anweisung.

Dies ermöglicht Folgendes:
  • Die enthaltenen Anweisungen können Hauptteil einer Funktion oder Prozedur sein.
  • Die Ausnahmen der Anweisungen können von einer Steuerroutine verarbeitet werden.
  • Die Ausführung der Anweisungen kann von einer LEAVE-Anweisung unterbrochen werden.

SYNTAX

Die zweite Bezeichnung kann nur präsent sein, wenn auch die erste Bezeichnung präsent ist. Wenn beide Bezeichnungen vorhanden sind, müssen sie identisch sein. Zwei oder mehr bezeichnete Anweisungen auf selber Ebene können dieselbe Bezeichnung haben. Dies schränkt jedoch die Vorteile der zweiten Bezeichnung teilweise ein. Der Vorteil besteht darin, dass die Bezeichnungen das ENDE (END) dem jeweiligen ANFANG (BEGIN) eindeutig und präzise zuordnet. Eine gekennzeichnete Anweisung, die in Anweisungen verschachtelt ist, kann jedoch nicht dieselbe Bezeichnung haben, da dies das Verhalten der Anweisungen ITERATE und LEAVE mehrdeutig machen würde.

Variablenbereich

Ein neuer lokale Variablenbereich wird unmittelbar nach BEGIN geöffnet, und deshalb verlieren alle Variablen in dieser Anweisung beim Erreichen von END ihre Gültigkeit. Wenn eine lokale Variable denselben Namen wie eine vorhandene Variable hat, greifen alle Verweise auf diesen Namen, die im Anschluss an die Deklaration vorkommen, auf die lokale Variable zu. Beispiel:
DECLARE Variable1 CHAR 'Existing variable';

-- Ein Verweis auf Variable1 gibt 'Vorhandene Variable' zurück

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

Wenn ATOMIC angegeben ist, darf nur eine Instanz eines Nachrichtenflusses (d. h. ein Thread) die Anweisungen einer bestimmten BEGIN ATOMIC... END-Anweisung (gekennzeichnet durch ihr Schema und ihre Bezeichnung) zu einem beliebigen Zeitpunkt ausführen. Ist keine Bezeichnung vorhanden, entspricht das Verhalten dem Fall, in dem eine Bezeichnung mit einer Länge von Null angegeben wurde.

Das Konstrukt BEGIN ATOMIC ist nützlich, wenn mehrere Änderungen an einer gemeinsamen Variablen vorgenommen werden und der Zwischenstatus der Daten für andere Instanzen nicht sichtbar sein soll. Betrachten Sie das folgende Code-Beispiel:
CREATE PROCEDURE WtiteSharedVariable1(IN NewValue CHARACTER)
SharedVariableMutex1 : BEGIN ATOMIC
  -- Neuen Wert in gemeinsame Variable setzen
             END;

CREATE FUNCTION ReadSharedVariable1() RETURNS CHARACTER
SharedVariableMutex1 : BEGIN ATOMIC
  DECLARE Value CHARACTER;
  -- Wert aus gemeinsamer Variablen abrufen
  RETURN Value;
END;
Im letzten Beispiel wird davon ausgegangen, dass sich die Prozedur WriteSharedVariable1 und die Funktion ReadSharedVariable1 im selben Schema befinden und von Knoten im selben Nachrichtenfluss verwendet werden. Es spielt jedoch keine Rolle, ob Prozedur und Funktion in Modulen enthalten sind oder ob sie im selben oder in unterschiedlichen Knoten verwendet werden. Der Broker stellt sicher, dass zu jeder Zeit nur ein Thread eine der Anweisungen in den ATOMIC-Abschnitten ausführt. Dadurch wird gewährleistet, dass z. B. zwei simultane Lese- und Schreibvorgänge seriell ausgeführt werden. Beachten Sie Folgendes:
  • Die serielle Verarbeitung ist auf den Fluss beschränkt. Zwei Flüsse, die BEGIN ATOMIC... END-Anweisungen mit demselben Schema und derselben Bezeichnung verwenden, können gleichzeitig ausgeführt werden. Insofern sind mehrere Instanzen innerhalb eines Flusses und mehrere Kopien eines Flusses nicht äquivalent.
  • Die serielle Verarbeitung wird durch das Schema und die Bezeichnung beschränkt. BEGIN ... END-Anweisungen mit ATOMIC, die in verschiedenen Schemas oder Bezeichnungen angegeben sind, können nicht miteinander interagieren.
Anmerkung: Sie können dies, wenn Sie es vorziehen, auf andere Art betrachten. Für jede Kombination aus Nachrichtenfluss, Schema und Bezeichnung verfügt der Broker über ein Mutex, das den zeitgleichen Zugriff auf die mit diesem Mutex verknüpften Anweisungen verhindert.

Verschachteln Sie keine BEGIN ATOMIC... END-Anweisungen, weder direkt noch indirekt, da dies zu einer "gegenseitigen Sperre" führt. Verwenden Sie aus diesem Grund keine PROPAGATE-Anweisung in einem ATOMIC-Block.

Es ist nicht notwendig, das BEGIN ATOMIC-Konstrukt in Flüssen zu verwenden, die nie mit mehr als einer Instanz implementiert werden (Sie sollten dies jedoch auch nicht dem Zufall überlassen). Weiterhin ist es nicht erforderlich, das BEGIN ATOMIC-Konstrukt für Lese- und Schreibvorgänge in gemeinsamen Variablen zu verwenden. Der Broker schreibt immer einen neuen Wert sicher in eine gemeinsame Variable bzw. liest den aktuellsten Wert sicher aus einer gemeinsamen Variablen. ATOMIC ist nur erforderlich, wenn der Anwendung keine Zwischenergebnisse angezeigt werden sollen.

Betrachten Sie das folgende Beispiel:
DECLARE LastOrderDate SHARED DATE;
...
SET LastOrderDate = CURRENT_DATE;
...
SET OutputRoot.XMLNSC.Data.Orders.Order[1].Date = LastOrderDate;
In diesem Beispiel gehen wir davon aus, dass ein Thread den Wert LastOrderDate (Datum des letzten Auftrags) periodisch aktualisiert und ein anderer Thread ihn periodisch liest. ATOMIC muss in diesem Fall nicht verwendet werden, da die zweite SET-Anweisung stets einen gültigen Wert liest. Wenn Aktualisierung und Lesevorgang sehr zeitnah ablaufen, kann nicht ermittelt werden, ob der alte oder der neue Wert gelesen wird, aber eines von beiden ist immer der Fall. Das Ergebnis enthält nie fehlerhafte Daten.
Betrachten Sie nun jedoch folgendes Beispiel:
DECLARE Count SHARED INT;
...
SET Count = Count + 1;
Bei diesem Beispiel gehen wir davon aus, dass mehrere Threads die SET-Ausführung periodisch ausführen. In diesem Fall müssen Sie kein ATOMIC verwenden, da zwei Threads den Wert Count (Anzahl) in fast demselben Augenblick lesen können und denselben Wert erhalten. Beide Threads führen die Addition durch, und beide speichern denselben Wert zurück. Das Endergebnis lautet daher N+1 und nicht N+2.

Der Broker stellt nicht automatisch eine höhere als diese Verriegelung bereit (z. B. eine Verriegelung der gesamten SET-Anweisung), da dies zu einer "gegenseitigen Sperre" führt.

Hinweis

Die BEGIN ... END-Anweisung ist ein Schleifenkonstrukt, das stets nur einmal abgearbeitet wird. Eine ITERATE- oder LEAVE-Anweisung, die in einer BEGIN ... END-Anweisung verschachtelt ist, hat demnach die erwartete Wirkung: die Steuerung wird an die Anweisung hinter END weitergeleitet. Die Verwendung der ITERATE- oder LEAVE-Anweisung in einer BEGIN ... END-Anweisung ist dann hilfreich, wenn eine lange Serie von Berechnungen abgebrochen werden muss, da ein bestimmtes Ergebnis erzielt wurde oder ein Fehler aufgetreten ist.

Zugehörige Konzepte
Übersicht zu ESQL
Zugehörige Tasks
ESQL erstellen
Zugehörige Verweise
Syntaxdiagramme: verfügbare Typen
ESQL-Anweisungen
Bemerkungen | Marken | Downloads | Bibliothek | Unterstützung | Rückmeldung
Copyright IBM Corporation 1999, 2006 Letzte Aktualisierung: 23. Aug. 2006
ak04940_