|
Prozesslogik "im Hintergrund" mit Fortschrittsbalken
Wenn Sie in Ihrer Application Express-Anwendung einen Seiten- oder Anwendungsprozeß
erstellen, so wird dieser im "Vordergrund" ausgeführt - Aus Sicht des Endbenutzers
wird die nächste Anwendungsseite während dieser Zeit geladen. Für "normale" Prozesse wie
Einfüge-, Änderungs- oder Löschoperationen auf Tabellen ist dies unproblematisch,
da sie nur kurze Zeit in Anspruch nehmen.
Nimmt die Ausführung der hinterlegten Logik jedoch längere Zeit in Anspruch, so
ist es meist nicht sinnvoll, mit der Darstellung der Seite zu
warten, bis die Ausführung des Prozesses abgeschlossen ist. Vielmehr sollte
die nächste Seite sofort (zusammen mit einigen Status-Informationen) dargestellt
werden. Wie Sie dies erreichen, erfahren Sie in dieser Ausgabe.
Als Beispiel soll die nachfolgende PL/SQL-Prozedur dienen. Um einen langlaufenden
Prozeß zu simulieren, wird die Prozedur DBMS_LOCK.SLEEP
verwendet. Normalerweise
hat nur der Datenbankadministrator Zugriff auf dieses PL/SQL-Paket - um das
Beispiel nachvollziehen zu können, benötigen Sie also
EXECUTE-Privilegien auf
DBMS_LOCK. Erstellen Sie die Prozedur mit dem
SQL Workshop, dem
SQL Developer oder SQL*Plus.
Würden Sie diesen Code als normalen onSubmit- oder
onLoad-Prozeß hinterlegen, müsste der
Endbenutzer eine Minute auf den Seitenaufbau warten. Daher wählen wir nun die andere
Strategie - die Ausführung im Hintergrund.
In der Online-Hilfe zu Application Express ist ebenfalls ein Kapitel
Running Background PL/SQL vorhanden - dort ist
dargestellt, wie die Aufgabe
mit den Mitteln von Application-Express (APEX_PLSQL_JOB)
realisiert werden kann. In diesem
Beispiel wird jedoch der "Standard" für Jobs in der Datenbank
(DBMS_SCHEDULER) verwendet. DBMS_SCHEDULER ist ab
Oracle10g verfügbar.
Dies hat für Sie den den Vorteil, dass Sie das Wissen auch außerhalb von
Application Express nutzen können - weiterhin ist
DBMS_SCHEDULER wesentlich
mächtiger als APEX_PLSQL_JOB.
So können Sie Jobs mit DBMS_SCHEDULER
zu einem bestimmten Zeitpunkt in der Zukunft oder wiederholt ausführen lassen.
Darüber hinaus erfahren Sie, wie Sie Informationen über den Arbeitsstand ihres
Prozesses in der Datenbank bekannt machen, so dass der Datenbankadministrator
über solche Prozesse informiert ist. Zur Nutzung von
DBMS_SCHEDULER wird das Systemprivileg
CREATE JOB benötigt - normalerweise ist es
Ihrem Application Express-Workspace bereits eingeräumt.
Erstellen Sie nun eine einfache Application Express-Anwendung mit einer
HTML-Region auf einer Seite. Fügen Sie eine Schaltfläche
Job starten hinzu.
Abbildung 1: Eine Seite in einer Application Express-Anwendung
Wenn auf die Schaltfläche geklickt wird, soll der oben dargestellte PL/SQL-Code
(Prozedur LANG_LAUFEND) im Hintergrund ausgeführt werden.
Dies erreichen Sie, indem Sie einen PL/SQL-Prozess
mit folgendem Code erstellen:
Abbildung 2: Seitenprozess erstellen - Ausführung bei Klick auf die Schaltfläche
Mit dem PL/SQL-Paket DBMS_SCHEDULER
(Dokumentation) wird der Job erzeugt, in diesem Fall sofort gestartet und nach Beendigung gelöscht. Bevor Sie Ihre Seite starten, fügen Sie ihr noch einen Bericht hinzu.
Wählen Sie SQL Bericht aus und
hinterlegen Sie die in Abbildung 3 dargestellte SQL-Abfrage.
Abbildung 3: Bericht erzeugen: aktuelle laufende Hintergrund-Prozesse
Die Data Dictionary View USER_SCHEDULER_JOBS
(Dokumentation) gibt Informationen über
die vorhandenen Jobs aus. Dieser Bericht selektiert nur den Namen
(JOB_NAME)
und den Status ( STATE).
Starten Sie die Seite nun neu und klicken Sie auf die Schaltläche
Job starten. Das Ergebnis sollte
wie folgt aussehen.
Abbildung 4: Gestarteter Hintergrundprozess
Sie sehen, dass der Endbenutzer die Kontrolle über die Applikation sofort
zurückbekommen hat. Mit Hilfe des Berichts erfahren Sie, ob ein Job im
Hintergrund läuft. Nun wäre es sinnvoll, dem Endbenutzer eine Information
über die voraussichtliche Dauer zu geben - quasi eine Art "Fortschrittsbalken"
zu implementieren.
Mit dem PL/SQL-Paket DBMS_APPLICATION_INFO (Dokumentation) können
Sie der Datenbank (und damit auch dem Datenbankadministrator) Informationen
über die gerade laufende Anwendung geben. So kennt der DBA die Dictionary
View V$SESSION_LONGOPS (Dokumentation) - diese enthält Informationen
über langlaufende Prozesse in der Datenbank.
Warum V$SESSION_LONGOPS und keine eigene Tabelle?
Wenn Sie die Status-Informationen in eine eigene Tabelle schreiben, haben
Sie zunächst den Nachteil, dass ein Bericht auf diese Tabelle keine Ergebnisse
zurückliefert, da der Hintergrund-Job in einer eigenen Datenbanksitzung
abläuft.
Solange hier kein COMMIT erfolgt, können Sie die Inhalte nicht
in einem Bericht anzeigen. Man könnte auch dieses Problem mit autonomen Transaktionen lösen, jedoch
stellt sich dann die Frage, wie die Tabelle wieder aufgeräumt wird. Außerdem
kennt der Datenbankadministrator Ihre Tabelle wahrscheinlich nicht.
V$SESSION_LONGOPS ist als Datenbank-Standard
genau für diese Anforderung vorhanden.
Im folgenden wird die zu Beginn erstellte Prozedur LANG_LAUFEND
so geändert, dass Informationen über den Bearbeitungsstand in der View
V$SESSION_LONGOPS bereitgestellt werden.
Dies geschieht mit dem Aufruf
von DBMS_APPLICATION_INFO.SET_SESSION_LONGOPS.
Ändern Sie nun noch den Bericht auf Ihrer Anwendungsseite. Es wird
nicht USER_SCHEDULER_JOBS, sondern
V$SESSION_LONGOPS abgefragt.
Abbildung 5: Änderung der Status-Abfrage: View V$SESSION_LONGOPS
Starten Sie nun nochmals die Seite und klicken Sie auf
Job starten . Wenn
Sie die Seite daraufhin in regelmäßigen Abständen mit der Taste <F5> neu laden, dann
stellen Sie fest, dass die Spalte PERCENT sich
langsam der 100 nähert.
Abbildung 6: Gestarteter Hintergrundprozeß: Sicht auf V$SESSION_LONGOPS (Spalte PERCENT)
Erweitern Sie zum Abschluß die Seite so, dass mit Hilfe der AJAX-Technologie
automatisch ein grafischer Balken angezeigt wird, der nach und nach auf 100%
läuft. Zunächst erzeugen Sie einen Anwendungsprozeß - dieser gibt zurück,
zu wieviel Prozent der Job bearbeitet ist. Geben Sie dem Prozeß den Namen
getJobStatus.
Abbildung 7: Anwendungsprozess erstellen
Hinterlegen Sie nun im Seiten-Footer etwas JavaScript-Code zum Laden und
Darstellen des Fortschrittsbalkens.
Zum Abschluß muss folgender HTML-Code hinterlegt werden - an dieser Stelle
wird dann der Fortschrittsbalken erscheinen. Sie können eine bestehende
Region nehmen oder eine neue HTML-Region anlegen. Wichtig dabei ist die Element-ID
PROGRESSBAR - diese wird vom JavaScript-Code aus
referenziert.
Abbildung 8: "Container" für den Fortschrittsbalken erzeugen
Starten Sie die Seite nun neu und klicken Sie auf Job starten. Das Ergebnis
sollte dann wie folgt aussehen:
Abbildung 9: Das Ergebnis: Fortschrittsbalken
Neben dieser Darstellung in der Applikation selbst können die Informationen
auch über SQL*Plus abgerufen werden - schließlich verwenden Sie hier eine dem Oracle-DBA
wohlbekannte View. Anhand der Spalten SOFAR und
TOTALWORK ist erkennbar, dass
der Job zu 50% erledigt ist.
In der nächsten Ausgabe befassen wir uns näher mit DBMS_SCHEDULER - dann lernen Sie, wie
Sie einen Job wiederholt ausführen und dabei auch einen komplexeren Zeitplan verwenden können.
Abbildung 10: V$SESSION_LONGOPS auf der Kommandozeile
Zurück zur Community-Seite
|